diff --git a/pcweb/pages/landing/landing.py b/pcweb/pages/landing/landing.py index 8c8bf9773f..1c5ab66d01 100644 --- a/pcweb/pages/landing/landing.py +++ b/pcweb/pages/landing/landing.py @@ -11,6 +11,9 @@ from pcweb.pages.landing.views.products import products from pcweb.pages.landing.views.security import security from pcweb.pages.landing.views.start_building import start_building +from pcweb.pages.landing.views.companies import companies +from pcweb.meta.meta import meta_tags +from pcweb.pages.landing.views.outcomes_section import outcomes_section from pcweb.pages.landing.views.use_cases import use_cases from pcweb.pages.landing.views.video_demo import video_demo from pcweb.templates.mainpage import mainpage @@ -27,6 +30,7 @@ def landing() -> rx.Component: ai_section(), framework_section(), hosting_section(), + outcomes_section(), security(), start_building(), # stats(), diff --git a/pcweb/pages/landing/views/outcomes_section.py b/pcweb/pages/landing/views/outcomes_section.py new file mode 100644 index 0000000000..be312c7354 --- /dev/null +++ b/pcweb/pages/landing/views/outcomes_section.py @@ -0,0 +1,218 @@ +import reflex as rx + +from pcweb.components.icons import get_icon +from pcweb.components.button import button +from typing import List + + +# Outcomes features data +OUTCOMES_FEATURES = [ + { + "title": "Dedicated Engineer", + "description": "An expert engineer is assigned to your team to build your first app.", + "icon": "backend_auth", + }, + { + "title": "Fast Time to Launch", + "description": "Get your first app up and running quickly with expert guidance.", + "icon": "arrow_top_right", + }, + { + "title": "Guaranteed Success", + "description": "We ensure your app reaches a successful state before handoff.", + "icon": "star", + }, + { + "title": "Training and Enablement", + "description": "Hands-on training so your team can maintain and extend your app.", + "icon": "document_code", + }, +] + + +def header() -> rx.Component: + return rx.box( + rx.el.h3( + "Deliver Outcomes", + class_name="text-slate-12 text-3xl font-semibold text-center", + ), + rx.el.p( + "Your success, guaranteed. Real outcomes, real support", + class_name="text-slate-9 text-xl font-semibold text-center", + ), + class_name="flex items-center justify-between text-slate-11 flex-col py-[5rem] 2xl:border-x border-t border-slate-4 max-w-[64.19rem] mx-auto w-full", + ) + + +def outcomes_showcase() -> rx.Component: + """Central outcomes showcase component with prominent display.""" + return rx.box( + # Radial background + rx.html( + """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""", + class_name="shrink-0 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-[-3] pointer-events-none hidden lg:flex", + ), + # Gradial blur + rx.html( + """ + + + + + + + + +""", + class_name="shrink-0 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-[-2] pointer-events-none", + ), + rx.box( + rx.el.h2( + "Powerful Outcomes", + class_name="text-2xl font-semibold text-slate-12 text-center", + ), + rx.el.p( + "Everything you need to achieve your goals", + class_name="font-medium text-slate-9 text-center mt-2", + ), + rx.link( + button( + "Book Demo Now!", + class_name="!h-10 mt-6 !font-small-smbold !rounded-[0.625rem] whitespace-nowrap w-48", + ), + underline="none", + is_external=True, + href="/pricing", + ), + class_name="flex flex-col justify-center items-center h-full", + ), + class_name="desktop-only h-full w-full flex flex-col justify-center items-center relative overflow-hidden row-span-2 col-span-1 border border-slate-3", + ) + +def outcomes_card( + title: str, + description: str, + icon: str, + cols: str = "1", + class_name: str = "", +) -> rx.Component: + """Individual outcomes feature card component.""" + return rx.box( + rx.box( + _card_header(title, icon), + _card_description(description), + class_name="flex flex-col gap-[0.875rem]", + ), + class_name=f"col-span-{cols} h-[11rem] overflow-hidden p-8 w-full {class_name}", + ) + +def _card_header(title: str, icon: str) -> rx.Component: + """Card header with icon and title.""" + return rx.box( + get_icon(icon, class_name="!text-slate-9"), + rx.el.h3(title, class_name="text-slate-12 text-base font-semibold"), + class_name="flex flex-row items-center gap-2", + ) + +def _card_description(description: str) -> rx.Component: + """Card description text.""" + return rx.el.p(description, class_name="text-slate-9 font-medium text-sm text-start") + +def _create_grid_items() -> List[rx.Component]: + """Creates the grid items with outcomes showcase in the center.""" + grid_items = [] + + # Add first outcomes card + grid_items.append(outcomes_card(**OUTCOMES_FEATURES[0])) + + # Add the central outcomes showcase + grid_items.append(outcomes_showcase()) + + # Add remaining outcomes cards + for feature in OUTCOMES_FEATURES[1:]: + grid_items.append(outcomes_card(**feature)) + + return grid_items + +def outcomes_grid() -> rx.Component: + """Main outcomes features grid component.""" + return rx.box( + *_create_grid_items(), + class_name="grid grid-cols-1 lg:grid-cols-3 gap-0 grid-rows-2 lg:grid-rows-2 w-full divide-y divide-slate-3 border border-slate-3", + ) + +def outcomes_section() -> rx.Component: + return rx.el.section( + header(), + rx.box( + outcomes_grid(), + class_name="flex flex-row max-w-[64.19rem] justify-center w-full", + ), + class_name="flex flex-col mx-auto w-full max-w-[84.19rem] relative justify-center items-center", + )