From c47ec1b452172561d8ab2e0ea7f8266a958f8bdb Mon Sep 17 00:00:00 2001 From: marks Date: Tue, 15 Jul 2025 15:17:21 -0500 Subject: [PATCH 1/4] Landing page for Maple Teams --- frontend/src/components/Footer.tsx | 6 + frontend/src/components/TopNav.tsx | 4 + frontend/src/routeTree.gen.ts | 26 +++++ frontend/src/routes/teams.tsx | 177 +++++++++++++++++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 frontend/src/routes/teams.tsx diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index be55e0e9..4a65cc51 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -70,6 +70,12 @@ export function Footer() { > Security Proof + + Teams +
diff --git a/frontend/src/components/TopNav.tsx b/frontend/src/components/TopNav.tsx index f4b60fce..de8ed404 100644 --- a/frontend/src/components/TopNav.tsx +++ b/frontend/src/components/TopNav.tsx @@ -52,6 +52,7 @@ export function TopNav() {
Pricing Proof + Teams setMobileMenuOpen(false)}> Proof + setMobileMenuOpen(false)}> + Teams + rootRoute, +} as any) + const SignupRoute = SignupImport.update({ id: '/signup', path: '/signup', @@ -206,6 +213,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof SignupImport parentRoute: typeof rootRoute } + '/teams': { + id: '/teams' + path: '/teams' + fullPath: '/teams' + preLoaderRoute: typeof TeamsImport + parentRoute: typeof rootRoute + } '/password-reset/confirm': { id: '/password-reset/confirm' path: '/confirm' @@ -280,6 +294,7 @@ export interface FileRoutesByFullPath { '/pricing': typeof PricingRoute '/proof': typeof ProofRoute '/signup': typeof SignupRoute + '/teams': typeof TeamsRoute '/password-reset/confirm': typeof PasswordResetConfirmRoute '/verify/$code': typeof VerifyCodeRoute '/chat/$chatId': typeof AuthChatChatIdRoute @@ -299,6 +314,7 @@ export interface FileRoutesByTo { '/pricing': typeof PricingRoute '/proof': typeof ProofRoute '/signup': typeof SignupRoute + '/teams': typeof TeamsRoute '/password-reset/confirm': typeof PasswordResetConfirmRoute '/verify/$code': typeof VerifyCodeRoute '/chat/$chatId': typeof AuthChatChatIdRoute @@ -319,6 +335,7 @@ export interface FileRoutesById { '/pricing': typeof PricingRoute '/proof': typeof ProofRoute '/signup': typeof SignupRoute + '/teams': typeof TeamsRoute '/password-reset/confirm': typeof PasswordResetConfirmRoute '/verify/$code': typeof VerifyCodeRoute '/_auth/chat/$chatId': typeof AuthChatChatIdRoute @@ -340,6 +357,7 @@ export interface FileRouteTypes { | '/pricing' | '/proof' | '/signup' + | '/teams' | '/password-reset/confirm' | '/verify/$code' | '/chat/$chatId' @@ -358,6 +376,7 @@ export interface FileRouteTypes { | '/pricing' | '/proof' | '/signup' + | '/teams' | '/password-reset/confirm' | '/verify/$code' | '/chat/$chatId' @@ -376,6 +395,7 @@ export interface FileRouteTypes { | '/pricing' | '/proof' | '/signup' + | '/teams' | '/password-reset/confirm' | '/verify/$code' | '/_auth/chat/$chatId' @@ -396,6 +416,7 @@ export interface RootRouteChildren { PricingRoute: typeof PricingRoute ProofRoute: typeof ProofRoute SignupRoute: typeof SignupRoute + TeamsRoute: typeof TeamsRoute VerifyCodeRoute: typeof VerifyCodeRoute AuthProviderCallbackRoute: typeof AuthProviderCallbackRoute TeamInviteInviteIdRoute: typeof TeamInviteInviteIdRoute @@ -413,6 +434,7 @@ const rootRouteChildren: RootRouteChildren = { PricingRoute: PricingRoute, ProofRoute: ProofRoute, SignupRoute: SignupRoute, + TeamsRoute: TeamsRoute, VerifyCodeRoute: VerifyCodeRoute, AuthProviderCallbackRoute: AuthProviderCallbackRoute, TeamInviteInviteIdRoute: TeamInviteInviteIdRoute, @@ -439,6 +461,7 @@ export const routeTree = rootRoute "/pricing", "/proof", "/signup", + "/teams", "/verify/$code", "/auth/$provider/callback", "/team/invite/$inviteId" @@ -483,6 +506,9 @@ export const routeTree = rootRoute "/signup": { "filePath": "signup.tsx" }, + "/teams": { + "filePath": "teams.tsx" + }, "/password-reset/confirm": { "filePath": "password-reset.confirm.tsx", "parent": "/password-reset" diff --git a/frontend/src/routes/teams.tsx b/frontend/src/routes/teams.tsx new file mode 100644 index 00000000..a2e44527 --- /dev/null +++ b/frontend/src/routes/teams.tsx @@ -0,0 +1,177 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { TopNav } from "@/components/TopNav"; +import { FullPageMain } from "@/components/FullPageMain"; +import { MarketingHeader } from "@/components/MarketingHeader"; +import { Shield, Lock, Users, Sparkles, Building2, ArrowRight, FileText } from "lucide-react"; +import { Link } from "@tanstack/react-router"; + +export const Route = createFileRoute("/teams")({ + component: TeamsPage +}); + +function FeatureCard({ icon: Icon, title, description }: { icon: React.ElementType; title: string; description: string }) { + return ( +
+
+ +
+

{title}

+

{description}

+
+ ); +} + +function TeamsPage() { + return ( + <> + + + Confidential AI for Teams} + subtitle={ + + Secure, private AI for organizations that value trust. Collaborate with confidence—Maple Teams keeps your data safe, even from us. + + } + /> + + {/* Hero CTA */} +
+ + Get Started with Teams + + + Request a Demo + +
+ + {/* Features Section */} +
+
+
+

+ Why Choose Maple Teams? +

+

+ Maple Teams is built for organizations that handle sensitive data—law firms, therapy practices, non-profits, and businesses that demand privacy. Share AI access, pool usage, and collaborate securely with end-to-end encryption and confidential computing. +

+
+
+ + + +
+
+
+ + {/* Security Section */} +
+
+
+

+ Security by Design +

+

+ Maple Teams is built from the ground up for privacy and compliance. Your data is protected at every step—by cryptography, hardware, and open-source transparency. +

+
+
+ + + +
+
+
+ + {/* How It Works Section */} +
+
+
+

+ How Maple Teams Works +

+
+
    +
  1. Purchase seats for your team
  2. +
  3. Invite members by email
  4. +
  5. Use AI securely with your data, encrypted
  6. +
+
+
+
+
+
+ + For Businesses +
+

+ Maple Teams is trusted by organizations in law, healthcare, finance, and consulting. Draft contracts, analyze client data, and collaborate on sensitive projects with full privacy and compliance. +

+
+
+
+ + For Non-Profits +
+

+ Non-profits and advocacy groups use Maple to securely manage sensitive information, collaborate on grant writing, and protect the privacy of those they serve—no IT headaches, just secure, private AI for your mission. +

+
+
+
+
+ + {/* Pricing/CTA Section */} +
+
+

+ Simple, Transparent Pricing +

+

+ $30/month per seat. All features included. Priority support for teams. No hidden fees. +

+ + View Team Pricing + +
+ Need a larger deployment or have compliance questions? Contact us for enterprise options. +
+
+
+ + + ); +} \ No newline at end of file From 1d411db1c4851d8f970f7c33be5de1685340b232 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:32:33 +0000 Subject: [PATCH 2/4] Fix code review issues in Teams landing page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unused Link import that was causing TypeScript build errors - Fix conflicting CSS grid classes (md:grid-cols-2 vs md:grid-cols-3) - Replace anchor tags with proper Link components for internal navigation - Use search prop instead of query params in to prop for TypeScript compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Marks --- frontend/src/routes/teams.tsx | 70 +++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/frontend/src/routes/teams.tsx b/frontend/src/routes/teams.tsx index a2e44527..86e904a9 100644 --- a/frontend/src/routes/teams.tsx +++ b/frontend/src/routes/teams.tsx @@ -9,7 +9,15 @@ export const Route = createFileRoute("/teams")({ component: TeamsPage }); -function FeatureCard({ icon: Icon, title, description }: { icon: React.ElementType; title: string; description: string }) { +function FeatureCard({ + icon: Icon, + title, + description +}: { + icon: React.ElementType; + title: string; + description: string; +}) { return (
@@ -27,22 +35,28 @@ function TeamsPage() { Confidential AI for Teams} + title={ + + Confidential AI for Teams + + } subtitle={ - Secure, private AI for organizations that value trust. Collaborate with confidence—Maple Teams keeps your data safe, even from us. + Secure, private AI for organizations that value trust. Collaborate with + confidence—Maple Teams keeps your data safe, even from us. } /> {/* Hero CTA */}
- Get Started with Teams - +

- Why Choose Maple Teams? + Why Choose{" "} + Maple Teams?

- Maple Teams is built for organizations that handle sensitive data—law firms, therapy practices, non-profits, and businesses that demand privacy. Share AI access, pool usage, and collaborate securely with end-to-end encryption and confidential computing. + Maple Teams is built for organizations that handle sensitive data—law firms, therapy + practices, non-profits, and businesses that demand privacy. Share AI access, pool + usage, and collaborate securely with end-to-end encryption and confidential + computing.

@@ -90,10 +108,11 @@ function TeamsPage() { Security by Design

- Maple Teams is built from the ground up for privacy and compliance. Your data is protected at every step—by cryptography, hardware, and open-source transparency. + Maple Teams is built from the ground up for privacy and compliance. Your data is + protected at every step—by cryptography, hardware, and open-source transparency.

-
+
-

- How Maple Teams Works -

+

How Maple Teams Works

  1. Purchase seats for your team
  2. @@ -135,7 +152,9 @@ function TeamsPage() { For Businesses

- Maple Teams is trusted by organizations in law, healthcare, finance, and consulting. Draft contracts, analyze client data, and collaborate on sensitive projects with full privacy and compliance. + Maple Teams is trusted by organizations in law, healthcare, finance, and + consulting. Draft contracts, analyze client data, and collaborate on sensitive + projects with full privacy and compliance.

@@ -144,7 +163,9 @@ function TeamsPage() { For Non-Profits

- Non-profits and advocacy groups use Maple to securely manage sensitive information, collaborate on grant writing, and protect the privacy of those they serve—no IT headaches, just secure, private AI for your mission. + Non-profits and advocacy groups use Maple to securely manage sensitive + information, collaborate on grant writing, and protect the privacy of those they + serve—no IT headaches, just secure, private AI for your mission.

@@ -154,24 +175,27 @@ function TeamsPage() { {/* Pricing/CTA Section */}
-

- Simple, Transparent Pricing -

+

Simple, Transparent Pricing

$30/month per seat. All features included. Priority support for teams. No hidden fees.

-
View Team Pricing - +
- Need a larger deployment or have compliance questions? Contact us for enterprise options. + Need a larger deployment or have compliance questions?{" "} + + Contact us + {" "} + for enterprise options.
); -} \ No newline at end of file +} From 429572b8f250d6c30e7848a09b382de04a0cf454 Mon Sep 17 00:00:00 2001 From: marks Date: Tue, 15 Jul 2025 15:47:08 -0500 Subject: [PATCH 3/4] Add Learn More link to blog post and show the Pricing matrix for Team at the bottom CTA --- frontend/src/components/Marketing.tsx | 2 ++ frontend/src/routes/teams.tsx | 31 +++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/Marketing.tsx b/frontend/src/components/Marketing.tsx index b2694533..007361d5 100644 --- a/frontend/src/components/Marketing.tsx +++ b/frontend/src/components/Marketing.tsx @@ -182,6 +182,8 @@ function PricingTier({ ); } +export { PricingTier }; + export function Marketing() { const [isIOS, setIsIOS] = useState(false); diff --git a/frontend/src/routes/teams.tsx b/frontend/src/routes/teams.tsx index 86e904a9..d9962219 100644 --- a/frontend/src/routes/teams.tsx +++ b/frontend/src/routes/teams.tsx @@ -4,6 +4,8 @@ import { FullPageMain } from "@/components/FullPageMain"; import { MarketingHeader } from "@/components/MarketingHeader"; import { Shield, Lock, Users, Sparkles, Building2, ArrowRight, FileText } from "lucide-react"; import { Link } from "@tanstack/react-router"; +import { PricingTier } from "@/components/Marketing"; +import { PRICING_PLANS } from "@/config/pricingConfig"; export const Route = createFileRoute("/teams")({ component: TeamsPage @@ -144,6 +146,16 @@ function TeamsPage() {
  • Use AI securely with your data, encrypted
  • +
    @@ -179,13 +191,18 @@ function TeamsPage() {

    $30/month per seat. All features included. Priority support for teams. No hidden fees.

    - - View Team Pricing - +
    +
    + plan.name === "Team")!.name} + price={PRICING_PLANS.find(plan => plan.name === "Team")!.price} + description={PRICING_PLANS.find(plan => plan.name === "Team")!.description} + features={PRICING_PLANS.find(plan => plan.name === "Team")!.features} + ctaText={PRICING_PLANS.find(plan => plan.name === "Team")!.ctaText} + popular={PRICING_PLANS.find(plan => plan.name === "Team")!.popular} + /> +
    +
    Need a larger deployment or have compliance questions?{" "} From da2ed270508e94fb711d6817020ac1ae35732d67 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:06:42 +0000 Subject: [PATCH 4/4] Fix Footer.tsx to use Link components for internal navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace anchor tags with proper Link components for internal routes: - /pricing - /downloads - /proof - /teams This ensures proper SPA behavior and addresses the remaining code review issues. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Marks --- frontend/src/components/Footer.tsx | 25 +++++++++++++------------ frontend/src/routes/teams.tsx | 12 ++++++------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index 4a65cc51..f8820037 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -1,4 +1,5 @@ import { Github, Twitter, Mail } from "lucide-react"; +import { Link } from "@tanstack/react-router"; import { DiscordIcon } from "./icons/DiscordIcon"; export function Footer() { @@ -52,30 +53,30 @@ export function Footer() {
    diff --git a/frontend/src/routes/teams.tsx b/frontend/src/routes/teams.tsx index d9962219..262a49eb 100644 --- a/frontend/src/routes/teams.tsx +++ b/frontend/src/routes/teams.tsx @@ -194,12 +194,12 @@ function TeamsPage() {
    plan.name === "Team")!.name} - price={PRICING_PLANS.find(plan => plan.name === "Team")!.price} - description={PRICING_PLANS.find(plan => plan.name === "Team")!.description} - features={PRICING_PLANS.find(plan => plan.name === "Team")!.features} - ctaText={PRICING_PLANS.find(plan => plan.name === "Team")!.ctaText} - popular={PRICING_PLANS.find(plan => plan.name === "Team")!.popular} + name={PRICING_PLANS.find((plan) => plan.name === "Team")!.name} + price={PRICING_PLANS.find((plan) => plan.name === "Team")!.price} + description={PRICING_PLANS.find((plan) => plan.name === "Team")!.description} + features={PRICING_PLANS.find((plan) => plan.name === "Team")!.features} + ctaText={PRICING_PLANS.find((plan) => plan.name === "Team")!.ctaText} + popular={PRICING_PLANS.find((plan) => plan.name === "Team")!.popular} />