use dioxus::prelude::*; use dioxus_free_icons::icons::bs_icons::{ BsArrowRight, BsGlobe2, BsKey, BsRobot, BsServer, BsShieldCheck, }; use dioxus_free_icons::icons::fa_solid_icons::FaCubes; use dioxus_free_icons::Icon; use crate::i18n::{t, Locale}; use crate::Route; /// Public landing page for the CERTifAI platform. /// /// Displays a marketing-oriented page with hero section, feature grid, /// how-it-works steps, and call-to-action banners. This page is accessible /// without authentication. #[component] pub fn LandingPage() -> Element { rsx! { div { class: "landing", LandingNav {} HeroSection {} SocialProof {} FeaturesGrid {} HowItWorks {} CtaBanner {} LandingFooter {} } } } /// Sticky top navigation bar with logo, nav links, and CTA buttons. #[component] fn LandingNav() -> Element { let locale = use_context::>(); let l = *locale.read(); rsx! { nav { class: "landing-nav", div { class: "landing-nav-inner", Link { to: Route::LandingPage {}, class: "landing-logo", span { class: "landing-logo-icon", Icon { icon: BsShieldCheck, width: 24, height: 24 } } span { "CERTifAI" } } div { class: "landing-nav-links", a { href: "#features", {t(l, "common.features")} } a { href: "#how-it-works", {t(l, "common.how_it_works")} } a { href: "#pricing", {t(l, "nav.pricing")} } } div { class: "landing-nav-actions", Link { to: Route::Login { redirect_url: "/dashboard".into(), }, class: "btn btn-ghost btn-sm", {t(l, "common.log_in")} } Link { to: Route::Login { redirect_url: "/dashboard".into(), }, class: "btn btn-primary btn-sm", {t(l, "common.get_started")} } } } } } } /// Hero section with headline, subtitle, and CTA buttons. #[component] fn HeroSection() -> Element { let locale = use_context::>(); let l = *locale.read(); rsx! { section { class: "hero-section", div { class: "hero-content", div { class: "hero-badge badge badge-outline", {t(l, "landing.badge")} } h1 { class: "hero-title", {t(l, "landing.hero_title_1")} br {} span { class: "hero-title-accent", {t(l, "landing.hero_title_2")} } } p { class: "hero-subtitle", {t(l, "landing.hero_subtitle")} } div { class: "hero-actions", Link { to: Route::Login { redirect_url: "/dashboard".into(), }, class: "btn btn-primary btn-lg", {t(l, "common.get_started")} Icon { icon: BsArrowRight, width: 18, height: 18 } } a { href: "#features", class: "btn btn-outline btn-lg", {t(l, "landing.learn_more")} } } } div { class: "hero-graphic", // Abstract shield/network SVG motif svg { view_box: "0 0 400 400", fill: "none", width: "100%", height: "100%", // Gradient definitions defs { linearGradient { id: "grad1", x1: "0%", y1: "0%", x2: "100%", y2: "100%", stop { offset: "0%", stop_color: "#91a4d2" } stop { offset: "100%", stop_color: "#6d85c6" } } linearGradient { id: "grad2", x1: "0%", y1: "100%", x2: "100%", y2: "0%", stop { offset: "0%", stop_color: "#f97066" } stop { offset: "100%", stop_color: "#f9a066" } } radialGradient { id: "glow", cx: "50%", cy: "50%", r: "50%", stop { offset: "0%", stop_color: "rgba(145,164,210,0.3)", } stop { offset: "100%", stop_color: "rgba(145,164,210,0)", } } } // Background glow circle { cx: "200", cy: "200", r: "180", fill: "url(#glow)", } // Shield outline path { d: "M200 40 L340 110 L340 230 C340 300 270 360 200 380 \ C130 360 60 300 60 230 L60 110 Z", stroke: "url(#grad1)", stroke_width: "2", fill: "none", opacity: "0.6", } // Inner shield path { d: "M200 80 L310 135 L310 225 C310 280 255 330 200 345 \ C145 330 90 280 90 225 L90 135 Z", stroke: "url(#grad1)", stroke_width: "1.5", fill: "rgba(145,164,210,0.05)", opacity: "0.8", } // Network nodes circle { cx: "200", cy: "180", r: "8", fill: "url(#grad1)", } circle { cx: "150", cy: "230", r: "6", fill: "url(#grad2)", } circle { cx: "250", cy: "230", r: "6", fill: "url(#grad2)", } circle { cx: "200", cy: "280", r: "6", fill: "url(#grad1)", } circle { cx: "130", cy: "170", r: "4", fill: "#91a4d2", opacity: "0.6", } circle { cx: "270", cy: "170", r: "4", fill: "#91a4d2", opacity: "0.6", } // Network connections line { x1: "200", y1: "180", x2: "150", y2: "230", stroke: "#91a4d2", stroke_width: "1", opacity: "0.4", } line { x1: "200", y1: "180", x2: "250", y2: "230", stroke: "#91a4d2", stroke_width: "1", opacity: "0.4", } line { x1: "150", y1: "230", x2: "200", y2: "280", stroke: "#91a4d2", stroke_width: "1", opacity: "0.4", } line { x1: "250", y1: "230", x2: "200", y2: "280", stroke: "#91a4d2", stroke_width: "1", opacity: "0.4", } line { x1: "200", y1: "180", x2: "130", y2: "170", stroke: "#91a4d2", stroke_width: "1", opacity: "0.3", } line { x1: "200", y1: "180", x2: "270", y2: "170", stroke: "#91a4d2", stroke_width: "1", opacity: "0.3", } // Checkmark inside shield center path { d: "M180 200 L195 215 L225 185", stroke: "url(#grad1)", stroke_width: "3", stroke_linecap: "round", stroke_linejoin: "round", fill: "none", } } } } } } /// Social proof / trust indicator strip. #[component] fn SocialProof() -> Element { let locale = use_context::>(); let l = *locale.read(); rsx! { section { class: "social-proof", p { class: "social-proof-text", {t(l, "landing.social_proof")} span { class: "social-proof-highlight", {t(l, "landing.data_sovereignty")} } } div { class: "social-proof-stats", div { class: "proof-stat", span { class: "proof-stat-value", "100%" } span { class: "proof-stat-label", {t(l, "landing.on_premise")} } } div { class: "proof-divider" } div { class: "proof-stat", span { class: "proof-stat-value", "GDPR" } span { class: "proof-stat-label", {t(l, "landing.compliant")} } } div { class: "proof-divider" } div { class: "proof-stat", span { class: "proof-stat-value", "EU" } span { class: "proof-stat-label", {t(l, "landing.data_residency")} } } div { class: "proof-divider" } div { class: "proof-stat", span { class: "proof-stat-value", "Zero" } span { class: "proof-stat-label", {t(l, "landing.third_party")} } } } } } } /// Feature cards grid section. #[component] fn FeaturesGrid() -> Element { let locale = use_context::>(); let l = *locale.read(); rsx! { section { id: "features", class: "features-section", h2 { class: "section-title", {t(l, "landing.features_title")} } p { class: "section-subtitle", {t(l, "landing.features_subtitle")} } div { class: "features-grid", FeatureCard { icon: rsx! { Icon { icon: BsServer, width: 28, height: 28 } }, title: t(l, "landing.feat_infra_title"), description: t(l, "landing.feat_infra_desc"), } FeatureCard { icon: rsx! { Icon { icon: BsShieldCheck, width: 28, height: 28 } }, title: t(l, "landing.feat_gdpr_title"), description: t(l, "landing.feat_gdpr_desc"), } FeatureCard { icon: rsx! { Icon { icon: FaCubes, width: 28, height: 28 } }, title: t(l, "landing.feat_llm_title"), description: t(l, "landing.feat_llm_desc"), } FeatureCard { icon: rsx! { Icon { icon: BsRobot, width: 28, height: 28 } }, title: t(l, "landing.feat_agent_title"), description: t(l, "landing.feat_agent_desc"), } FeatureCard { icon: rsx! { Icon { icon: BsGlobe2, width: 28, height: 28 } }, title: t(l, "landing.feat_mcp_title"), description: t(l, "landing.feat_mcp_desc"), } FeatureCard { icon: rsx! { Icon { icon: BsKey, width: 28, height: 28 } }, title: t(l, "landing.feat_api_title"), description: t(l, "landing.feat_api_desc"), } } } } } /// Individual feature card. /// /// # Arguments /// /// * `icon` - The icon element to display /// * `title` - Feature title (owned String from translation lookup) /// * `description` - Feature description text (owned String from translation lookup) #[component] fn FeatureCard(icon: Element, title: String, description: String) -> Element { rsx! { div { class: "card feature-card", div { class: "feature-card-icon", {icon} } h3 { class: "feature-card-title", "{title}" } p { class: "feature-card-desc", "{description}" } } } } /// Three-step "How It Works" section. #[component] fn HowItWorks() -> Element { let locale = use_context::>(); let l = *locale.read(); rsx! { section { id: "how-it-works", class: "how-it-works-section", h2 { class: "section-title", {t(l, "landing.how_title")} } p { class: "section-subtitle", {t(l, "landing.how_subtitle")} } div { class: "steps-grid", StepCard { number: "01", title: t(l, "landing.step_deploy"), description: t(l, "landing.step_deploy_desc"), } StepCard { number: "02", title: t(l, "landing.step_configure"), description: t(l, "landing.step_configure_desc"), } StepCard { number: "03", title: t(l, "landing.step_scale"), description: t(l, "landing.step_scale_desc"), } } } } } /// Individual step card. /// /// # Arguments /// /// * `number` - Step number string (e.g. "01") /// * `title` - Step title (owned String from translation lookup) /// * `description` - Step description text (owned String from translation lookup) #[component] fn StepCard(number: &'static str, title: String, description: String) -> Element { rsx! { div { class: "step-card", span { class: "step-number", "{number}" } h3 { class: "step-title", "{title}" } p { class: "step-desc", "{description}" } } } } /// Call-to-action banner before the footer. #[component] fn CtaBanner() -> Element { let locale = use_context::>(); let l = *locale.read(); rsx! { section { class: "cta-banner", h2 { class: "cta-title", {t(l, "landing.cta_title")} } p { class: "cta-subtitle", {t(l, "landing.cta_subtitle")} } div { class: "cta-actions", Link { to: Route::Login { redirect_url: "/dashboard".into(), }, class: "btn btn-primary btn-lg", {t(l, "landing.get_started_free")} Icon { icon: BsArrowRight, width: 18, height: 18 } } Link { to: Route::Login { redirect_url: "/dashboard".into(), }, class: "btn btn-outline btn-lg", {t(l, "common.log_in")} } } } } } /// Landing page footer with links and copyright. #[component] fn LandingFooter() -> Element { let locale = use_context::>(); let l = *locale.read(); rsx! { footer { class: "landing-footer", div { class: "landing-footer-inner", div { class: "footer-brand", div { class: "landing-logo", span { class: "landing-logo-icon", Icon { icon: BsShieldCheck, width: 20, height: 20 } } span { "CERTifAI" } } p { class: "footer-tagline", {t(l, "landing.footer_tagline")} } } div { class: "footer-links-group", h4 { class: "footer-links-heading", {t(l, "landing.product")} } a { href: "#features", {t(l, "common.features")} } a { href: "#how-it-works", {t(l, "common.how_it_works")} } a { href: "#pricing", {t(l, "nav.pricing")} } } div { class: "footer-links-group", h4 { class: "footer-links-heading", {t(l, "landing.legal")} } Link { to: Route::ImpressumPage {}, {t(l, "common.impressum")} } Link { to: Route::PrivacyPage {}, {t(l, "common.privacy_policy")} } } div { class: "footer-links-group", h4 { class: "footer-links-heading", {t(l, "landing.resources")} } a { href: "#", {t(l, "landing.documentation")} } a { href: "#", {t(l, "landing.api_reference")} } a { href: "#", {t(l, "landing.support")} } } } div { class: "footer-bottom", p { {t(l, "landing.copyright")} } } } } }