main
tsx 862 lines 35.8 KB
Raw
1 import type { Metadata } from "next";
2 import { allPosts } from "contentlayer/generated";
3 import Link from "next/link";
4 import TabbedRunner from "./components/TabbedRunner";
5 import { FaApple, FaGooglePlay, FaWindows } from "react-icons/fa";
6 import { StructuredData } from "@/components/structured-data";
7 import siteMetadata from "@/content/siteMetadata";
8 import { absoluteUrl, genPageMetadata } from "./seo";
9 import { FrameworkWordCycler } from "@/components/word-cycler";
10
11 const proofPoints = [
12 {
13 title: "One command",
14 description: "Run `smb` to deploy.",
15 },
16 {
17 title: "SSH-first",
18 description: "No extra layer between you and the server.",
19 },
20 {
21 title: "Live logs",
22 description: "Watch the deploy as it happens.",
23 },
24 {
25 title: "Fast rollbacks",
26 description: "One command back when something breaks.",
27 },
28 ];
29
30 const reasonsToChoose = [
31 {
32 title: "No platform maze",
33 description: "Run `smb`, watch the release, move on.",
34 },
35 {
36 title: "Built for real stacks",
37 description: "Node.js, Rails, and Vapor. That's it.",
38 },
39 {
40 title: "Closer to normal ops",
41 description: "SSH in, deploy out. Nothing new to learn.",
42 },
43 ];
44
45 const bestFit = [
46 "Small teams shipping web apps and APIs",
47 "Agencies managing client deployments",
48 "Founders who want deploys to be boring",
49 "Teams that like SSH and fewer moving parts",
50 ];
51
52 const featuredServices = [
53 {
54 name: "smbCloud Auth",
55 eyebrow: "Accounts and access",
56 title: "Hosted auth that stays out of the way.",
57 description:
58 "Handle sign-in, signup, sessions, custom domains, collaborators, and billing without adopting a giant identity platform first.",
59 bullets: [
60 "Hosted auth apps for end-user accounts",
61 "Simple plans from Starter to Business",
62 "A calmer alternative to Auth0, Clerk, and bundled platform auth",
63 ],
64 href: "/auth",
65 cta: "Explore Auth",
66 accent: "indigo",
67 },
68 {
69 name: "smbCloud Mail",
70 eyebrow: "Domain mail routing",
71 title: "Mail built around the inbox, not just the send API.",
72 description:
73 "Route domain email, keep forwarding simple, and store inbound history without stitching together a bigger mail suite than you need.",
74 bullets: [
75 "One Mail app per project",
76 "Inbox routes, forwarding, and stored inbound messages",
77 "A cleaner fit for teams comparing Resend, useSend, or SendGrid",
78 ],
79 href: "/mail",
80 cta: "Explore Mail",
81 accent: "orange",
82 },
83 ];
84
85 const deployComparisonPages = [
86 {
87 href: "/heroku-alternative",
88 eyebrow: "Deploy comparison",
89 title: "Heroku alternative",
90 description: "Simpler deploys, less platform in the middle.",
91 bullets: [
92 "Why some Rails, Node.js, and Vapor teams leave Heroku",
93 "Where smbCloud fits, and where it does not",
94 ],
95 },
96 {
97 href: "/railway-alternative",
98 eyebrow: "Deploy comparison",
99 title: "Railway alternative",
100 description: "A calmer deploy flow for teams that want less surface area.",
101 bullets: [
102 "What you gain from a narrower platform",
103 "Why some teams prefer less surface area",
104 ],
105 },
106 ];
107
108 const authComparisonPages = [
109 {
110 href: "/auth0-alternative",
111 eyebrow: "Auth comparison",
112 title: "Auth0 alternative",
113 description: "Hosted auth without the identity platform overhead.",
114 bullets: [
115 "Compare hosted sign-in, signup, and session flows against a bigger identity stack",
116 "See where smbCloud Auth fits for smaller teams that want less auth sprawl",
117 ],
118 },
119 {
120 href: "/clerk-alternative",
121 eyebrow: "Auth comparison",
122 title: "Clerk alternative",
123 description: "Auth that stays out of the way.",
124 bullets: [
125 "Compare developer-friendly hosted auth against a calmer auth workflow",
126 "See when smbCloud Auth is a better fit and when Clerk still makes more sense",
127 ],
128 },
129 ];
130
131 const gresiqComparisonPages = [
132 {
133 href: "/supabase-alternative",
134 eyebrow: "GresIQ comparison",
135 title: "Supabase alternative",
136 description: "A data layer that doesn't become its own platform.",
137 bullets: [
138 "Compare focused database management against a full BaaS platform",
139 "See when smbCloud GresIQ is the simpler fit and when Supabase still makes sense",
140 ],
141 },
142 {
143 href: "/planetscale-alternative",
144 eyebrow: "GresIQ comparison",
145 title: "PlanetScale alternative",
146 description:
147 "A database that ships with your app, no branching workflow required.",
148 bullets: [
149 "Compare database-per-project workflows against branch-based schema management",
150 "Honest tradeoffs between simplicity and scale",
151 ],
152 },
153 {
154 href: "/neon-alternative",
155 eyebrow: "GresIQ comparison",
156 title: "Neon alternative",
157 description:
158 "Always-on Postgres without cold starts or serverless trade-offs.",
159 bullets: [
160 "Compare always-on managed databases against serverless Postgres",
161 "See which fits better for teams that already use smbCloud Deploy or Auth",
162 ],
163 },
164 ];
165
166 const mailComparisonPages = [
167 {
168 href: "/resend-alternative",
169 eyebrow: "Mail comparison",
170 title: "Resend alternative",
171 description: "Starts with the inbox, not the send API.",
172 bullets: [
173 "Compare inbox-first mail workflows against sending-first tools",
174 "See where smbCloud Mail fits for routing, forwarding, and stored inbound mail",
175 ],
176 },
177 {
178 href: "/usesend-alternative",
179 eyebrow: "Mail comparison",
180 title: "useSend alternative",
181 description: "Managed mail without running the stack yourself.",
182 bullets: [
183 "A cleaner fit for domain inbox routes and forwarding",
184 "Honest tradeoffs between hosted mail and open-source sending infrastructure",
185 ],
186 },
187 {
188 href: "/sendgrid-alternative",
189 eyebrow: "Mail comparison",
190 title: "SendGrid alternative",
191 description: "Domain inboxes and inbound routing without the giant suite.",
192 bullets: [
193 "Compare inbox routes, forwarding, and stored inbound mail against send-heavy tooling",
194 "See when smbCloud Mail is the better bet and when it is not",
195 ],
196 },
197 ];
198
199 export const metadata: Metadata = {
200 ...genPageMetadata({
201 title: "Deploy, Auth, Mail, and GresIQ on one platform",
202 description:
203 "smbCloud brings four services together: ship Node.js, Rails, and Vapor apps with Deploy, handle sign-in and accounts with Auth, route domain email with Mail, and run your database with GresIQ.",
204 path: "/",
205 keywords: [
206 "smbCloud",
207 "SSH-first deploy platform",
208 "deploy Node.js app",
209 "deploy Ruby on Rails app",
210 "deploy Vapor app",
211 "hosted auth",
212 "authentication service",
213 "domain mail routing",
214 "managed Postgres database",
215 "Heroku alternative",
216 "Auth0 alternative",
217 "Resend alternative",
218 "small team deployment platform",
219 ],
220 }),
221 };
222
223 const homepageStructuredData = {
224 "@context": "https://schema.org",
225 "@graph": [
226 {
227 "@type": "WebPage",
228 "@id": absoluteUrl("/#webpage"),
229 url: absoluteUrl("/"),
230 name: "smbCloud homepage",
231 description: siteMetadata.description,
232 isPartOf: {
233 "@id": absoluteUrl("/#website"),
234 },
235 about: {
236 "@id": absoluteUrl("/#organization"),
237 },
238 },
239 {
240 "@type": "Service",
241 name: "smbCloud Deploy",
242 serviceType: "SSH-first application deployment platform",
243 provider: {
244 "@id": absoluteUrl("/#organization"),
245 },
246 areaServed: "Worldwide",
247 url: absoluteUrl("/"),
248 description:
249 "Deploy Node.js, Ruby on Rails, and Swift/Vapor apps with one command, live logs, and fast rollbacks.",
250 audience: {
251 "@type": "Audience",
252 audienceType: "Developers and small software teams",
253 },
254 },
255 {
256 "@type": "Service",
257 name: "smbCloud Auth",
258 serviceType: "Hosted authentication service",
259 provider: {
260 "@id": absoluteUrl("/#organization"),
261 },
262 areaServed: "Worldwide",
263 url: absoluteUrl("/auth"),
264 description:
265 "Hosted auth apps for sign-in, signup, sessions, collaborators, and account management.",
266 audience: {
267 "@type": "Audience",
268 audienceType: "Developers and software teams shipping user accounts",
269 },
270 },
271 {
272 "@type": "Service",
273 name: "smbCloud Mail",
274 serviceType: "Domain mail routing service",
275 provider: {
276 "@id": absoluteUrl("/#organization"),
277 },
278 areaServed: "Worldwide",
279 url: absoluteUrl("/mail"),
280 description:
281 "Domain inbox routes, forwarding, and stored inbound mail for teams that want calmer mail infrastructure.",
282 audience: {
283 "@type": "Audience",
284 audienceType:
285 "Businesses and software teams handling inbound domain email",
286 },
287 },
288 {
289 "@type": "Service",
290 name: "GresIQ",
291 serviceType: "Data and memory layer for AI apps",
292 provider: {
293 "@id": absoluteUrl("/#organization"),
294 },
295 areaServed: "Worldwide",
296 url: "https://gresiq.com/",
297 description:
298 "A Postgres-backed backend for AI apps: schemaless documents, realtime, row-level security, and vector search behind one API.",
299 audience: {
300 "@type": "Audience",
301 audienceType: "Developers building AI apps and agents",
302 },
303 },
304 ],
305 };
306
307 export default function Home() {
308 let publishedPosts = allPosts.filter((post) => post.published);
309 publishedPosts = publishedPosts.sort(
310 (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
311 );
312
313 return (
314 <div>
315 <StructuredData data={homepageStructuredData} />
316
317 <section className="relative overflow-hidden px-6 pt-24 pb-20 sm:pt-36 sm:pb-28 lg:px-8">
318 <div className="pointer-events-none absolute inset-x-0 top-0 -z-10 h-[600px] bg-[radial-gradient(ellipse_80%_50%_at_50%_0%,rgba(99,102,241,0.18),transparent)] dark:bg-[radial-gradient(ellipse_80%_50%_at_50%_0%,rgba(99,102,241,0.12),transparent)]" />
319
320 <div className="mx-auto max-w-4xl text-center">
321 <p className="mb-8 text-sm font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-500">
322 Start at the finish line: distribution.
323 </p>
324
325 <h1 className="text-5xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-7xl leading-[1.05]">
326 Enterprise power at{" "}
327 <span className="text-indigo-600 dark:text-indigo-400">
328 startup velocity
329 </span>
330 .
331 </h1>
332
333 <p className="mx-auto mt-8 max-w-2xl text-lg leading-8 text-slate-600 dark:text-slate-400">
334 smbCloud brings Deploy, Auth, Mail, and GresIQ together. Ship
335 your <FrameworkWordCycler /> app without running four separate
336 vendors.
337 </p>
338
339 <div className="mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
340 <Link
341 href="https://console.smbcloud.xyz"
342 target="_blank"
343 rel="noopener noreferrer"
344 className="w-full rounded-lg bg-indigo-600 px-8 py-3.5 text-sm font-semibold text-white shadow-lg shadow-indigo-500/20 transition-all hover:bg-indigo-500 hover:shadow-indigo-500/30 active:scale-[0.98] sm:w-auto"
345 >
346 Start free →
347 </Link>
348 <Link
349 href="/services"
350 className="inline-flex w-full items-center justify-center rounded-lg border border-slate-300 dark:border-white/[0.12] px-8 py-3.5 text-sm font-semibold text-slate-700 dark:text-slate-200 transition-colors hover:bg-slate-50 dark:hover:bg-white/[0.04] sm:w-auto"
351 >
352 Explore the platform
353 </Link>
354 </div>
355 </div>
356 </section>
357
358 <section className="px-6 pb-14 lg:px-8">
359 <div className="mx-auto max-w-5xl">
360 <div className="mb-10 max-w-3xl">
361 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
362 Start here
363 </p>
364 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-4xl">
365 Auth and Mail are two of the clearest ways into smbCloud.
366 </h2>
367 <p className="mt-5 text-base leading-8 text-slate-600 dark:text-slate-400">
368 If you're comparing auth vendors or trying to clean up your domain
369 mail setup, start with the product page that matches the job.
370 </p>
371 </div>
372
373 <div className="grid gap-6 lg:grid-cols-2">
374 {featuredServices.map((service) => (
375 <Link
376 key={service.name}
377 href={service.href}
378 className={`group rounded-2xl border p-8 transition-colors ${
379 service.accent === "orange"
380 ? "border-orange-200 bg-orange-50/70 hover:border-orange-300 hover:bg-orange-50 dark:border-orange-500/20 dark:bg-orange-500/10 dark:hover:border-orange-500/35 dark:hover:bg-orange-500/14"
381 : "border-indigo-200 bg-indigo-50/70 hover:border-indigo-300 hover:bg-indigo-50 dark:border-indigo-500/20 dark:bg-indigo-500/10 dark:hover:border-indigo-500/35 dark:hover:bg-indigo-500/14"
382 }`}
383 >
384 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-500">
385 {service.eyebrow}
386 </p>
387 <h3 className="mt-4 text-2xl font-bold tracking-tight text-slate-900 dark:text-white">
388 {service.title}
389 </h3>
390 <p className="mt-4 text-base leading-8 text-slate-600 dark:text-slate-400">
391 {service.description}
392 </p>
393 <ul className="mt-6 space-y-3 text-sm leading-6 text-slate-600 dark:text-slate-400">
394 {service.bullets.map((bullet) => (
395 <li key={bullet} className="flex gap-3">
396 <span
397 className={`mt-2 h-1.5 w-1.5 shrink-0 rounded-full ${
398 service.accent === "orange"
399 ? "bg-orange-500"
400 : "bg-indigo-500"
401 }`}
402 />
403 <span>{bullet}</span>
404 </li>
405 ))}
406 </ul>
407 <p
408 className={`mt-6 text-sm font-semibold ${
409 service.accent === "orange"
410 ? "text-orange-600 dark:text-orange-400"
411 : "text-indigo-600 dark:text-indigo-400"
412 }`}
413 >
414 {service.cta} →
415 </p>
416 </Link>
417 ))}
418 </div>
419 </div>
420 </section>
421
422 <section className="px-6 pb-12 lg:px-8">
423 <div className="mx-auto grid max-w-5xl gap-4 sm:grid-cols-2 lg:grid-cols-4">
424 {proofPoints.map((point) => (
425 <div
426 key={point.title}
427 className="rounded-xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.02] p-5"
428 >
429 <p className="text-sm font-semibold text-slate-900 dark:text-white">
430 {point.title}
431 </p>
432 <p className="mt-2 text-sm leading-relaxed text-slate-500 dark:text-slate-400">
433 {point.description}
434 </p>
435 </div>
436 ))}
437 </div>
438 </section>
439
440 <section className="px-6 pb-28 lg:px-8">
441 <div className="mx-auto max-w-3xl">
442 <p className="mb-8 text-center text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
443 One CLI. Multiple runtimes.
444 </p>
445 <TabbedRunner />
446 </div>
447 </section>
448
449 <section className="border-t border-slate-200 dark:border-white/[0.06] px-6 py-24 lg:px-8">
450 <div className="mx-auto max-w-5xl">
451 <div className="mb-16 max-w-3xl">
452 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
453 Why smbCloud
454 </p>
455 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-4xl">
456 Deploys should be boring.
457 </h2>
458 <p className="mt-5 text-base leading-8 text-slate-600 dark:text-slate-400">
459 Run `smb`. Watch the logs. Move on.
460 </p>
461 </div>
462
463 <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
464 {reasonsToChoose.map((reason) => (
465 <div
466 key={reason.title}
467 className="rounded-2xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.02] p-6"
468 >
469 <h3 className="text-lg font-semibold text-slate-900 dark:text-white">
470 {reason.title}
471 </h3>
472 <p className="mt-3 text-sm leading-7 text-slate-500 dark:text-slate-400">
473 {reason.description}
474 </p>
475 </div>
476 ))}
477 </div>
478 </div>
479 </section>
480
481 <section className="px-6 pb-24 lg:px-8">
482 <div className="mx-auto grid max-w-5xl gap-8 lg:grid-cols-[1.1fr_0.9fr]">
483 <div className="rounded-2xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.02] p-8">
484 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
485 Who it fits best
486 </p>
487 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
488 Good fit
489 </h2>
490 <ul className="mt-6 space-y-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
491 {bestFit.map((item) => (
492 <li key={item} className="flex gap-3">
493 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
494 <span>{item}</span>
495 </li>
496 ))}
497 </ul>
498 </div>
499
500 <div className="rounded-2xl border border-slate-200 dark:border-white/[0.06] bg-slate-50 dark:bg-white/[0.02] p-8">
501 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
502 Stack focus
503 </p>
504 <h2 className="mt-4 text-2xl font-bold tracking-tight text-slate-900 dark:text-white">
505 Supported stacks
506 </h2>
507 <div className="mt-6 space-y-4 text-sm text-slate-600 dark:text-slate-400">
508 <div className="rounded-xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.03] p-4">
509 <p className="font-semibold text-slate-900 dark:text-white">
510 Node.js
511 </p>
512 <p className="mt-1 leading-7">
513 Web apps, APIs, dashboards, backend services.
514 </p>
515 </div>
516 <div className="rounded-xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.03] p-4">
517 <p className="font-semibold text-slate-900 dark:text-white">
518 Ruby on Rails
519 </p>
520 <p className="mt-1 leading-7">
521 Still my favorite stack for shipping fast.
522 </p>
523 </div>
524 <div className="rounded-xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.03] p-4">
525 <p className="font-semibold text-slate-900 dark:text-white">
526 Swift / Vapor
527 </p>
528 <p className="mt-1 leading-7">
529 Works. Doesn't treat Vapor as an afterthought.
530 </p>
531 </div>
532 </div>
533 </div>
534 </div>
535 </section>
536
537 <section className="border-t border-slate-200 dark:border-white/[0.06] px-6 py-24 lg:px-8">
538 <div className="mx-auto max-w-5xl">
539 <div className="mb-16 max-w-3xl">
540 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
541 Compare services
542 </p>
543 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-4xl">
544 Pick the service you're comparing.
545 </h2>
546 </div>
547
548 <div className="space-y-16">
549 <div>
550 <div className="mb-10 max-w-3xl">
551 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
552 smbCloud Auth
553 </p>
554 <h3 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
555 Auth0, Clerk, or Supabase Auth?
556 </h3>
557 <p className="mt-4 text-base leading-8 text-slate-600 dark:text-slate-400">
558 Sign-in, signup, sessions. Hosted, out of the way.
559 </p>
560 </div>
561
562 <div className="grid gap-6 lg:grid-cols-3">
563 {authComparisonPages.map((page) => (
564 <Link
565 key={page.href}
566 href={page.href}
567 className="group rounded-2xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.02] p-8 transition-colors hover:border-indigo-300 dark:hover:border-indigo-700/50 hover:bg-slate-50 dark:hover:bg-white/[0.04]"
568 >
569 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
570 {page.eyebrow}
571 </p>
572 <h4 className="mt-4 text-2xl font-semibold tracking-tight text-slate-900 transition-colors group-hover:text-indigo-600 dark:text-white dark:group-hover:text-indigo-400">
573 {page.title}
574 </h4>
575 <p className="mt-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
576 {page.description}
577 </p>
578 <ul className="mt-5 space-y-3 text-sm leading-6 text-slate-500 dark:text-slate-400">
579 {page.bullets.map((bullet) => (
580 <li key={bullet} className="flex gap-3">
581 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
582 <span>{bullet}</span>
583 </li>
584 ))}
585 </ul>
586 <p className="mt-6 text-sm font-semibold text-indigo-600 dark:text-indigo-400">
587 Read comparison →
588 </p>
589 </Link>
590 ))}
591 </div>
592 </div>
593
594 <div className="border-t border-slate-200 pt-16 dark:border-white/[0.06]">
595 <div className="mb-10 max-w-3xl">
596 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
597 smbCloud Mail
598 </p>
599 <h3 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
600 Resend, useSend, or SendGrid?
601 </h3>
602 <p className="mt-4 text-base leading-8 text-slate-600 dark:text-slate-400">
603 Domain routes, forwarding, stored inbound mail.
604 </p>
605 </div>
606
607 <div className="grid gap-6 lg:grid-cols-3">
608 {mailComparisonPages.map((page) => (
609 <Link
610 key={page.href}
611 href={page.href}
612 className="group rounded-2xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.02] p-8 transition-colors hover:border-indigo-300 dark:hover:border-indigo-700/50 hover:bg-slate-50 dark:hover:bg-white/[0.04]"
613 >
614 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
615 {page.eyebrow}
616 </p>
617 <h4 className="mt-4 text-2xl font-semibold tracking-tight text-slate-900 transition-colors group-hover:text-indigo-600 dark:text-white dark:group-hover:text-indigo-400">
618 {page.title}
619 </h4>
620 <p className="mt-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
621 {page.description}
622 </p>
623 <ul className="mt-5 space-y-3 text-sm leading-6 text-slate-500 dark:text-slate-400">
624 {page.bullets.map((bullet) => (
625 <li key={bullet} className="flex gap-3">
626 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
627 <span>{bullet}</span>
628 </li>
629 ))}
630 </ul>
631 <p className="mt-6 text-sm font-semibold text-indigo-600 dark:text-indigo-400">
632 Read comparison →
633 </p>
634 </Link>
635 ))}
636 </div>
637 </div>
638
639 <div className="border-t border-slate-200 pt-16 dark:border-white/[0.06]">
640 <div className="mb-10 max-w-3xl">
641 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
642 smbCloud Deploy
643 </p>
644 <h3 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
645 Heroku or Railway?
646 </h3>
647 <p className="mt-4 text-base leading-8 text-slate-600 dark:text-slate-400">
648 Direct comparisons, honest about where smbCloud fits and where
649 it doesn't.
650 </p>
651 </div>
652
653 <div className="grid gap-6 lg:grid-cols-2">
654 {deployComparisonPages.map((page) => (
655 <Link
656 key={page.href}
657 href={page.href}
658 className="group rounded-2xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.02] p-8 transition-colors hover:border-indigo-300 dark:hover:border-indigo-700/50 hover:bg-slate-50 dark:hover:bg-white/[0.04]"
659 >
660 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
661 {page.eyebrow}
662 </p>
663 <h4 className="mt-4 text-2xl font-semibold tracking-tight text-slate-900 transition-colors group-hover:text-indigo-600 dark:text-white dark:group-hover:text-indigo-400">
664 {page.title}
665 </h4>
666 <p className="mt-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
667 {page.description}
668 </p>
669 <ul className="mt-5 space-y-3 text-sm leading-6 text-slate-500 dark:text-slate-400">
670 {page.bullets.map((bullet) => (
671 <li key={bullet} className="flex gap-3">
672 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
673 <span>{bullet}</span>
674 </li>
675 ))}
676 </ul>
677 <p className="mt-6 text-sm font-semibold text-indigo-600 dark:text-indigo-400">
678 Read comparison →
679 </p>
680 </Link>
681 ))}
682 </div>
683 </div>
684
685 <div className="border-t border-slate-200 pt-16 dark:border-white/[0.06]">
686 <div className="mb-10 max-w-3xl">
687 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
688 smbCloud GresIQ
689 </p>
690 <h3 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
691 Supabase, PlanetScale, or Neon?
692 </h3>
693 <p className="mt-4 text-base leading-8 text-slate-600 dark:text-slate-400">
694 A data layer that lives with your stack, not next to it.
695 </p>
696 </div>
697
698 <div className="grid gap-6 lg:grid-cols-3">
699 {gresiqComparisonPages.map((page) => (
700 <Link
701 key={page.href}
702 href={page.href}
703 className="group rounded-2xl border border-slate-200 dark:border-white/[0.06] bg-white dark:bg-white/[0.02] p-8 transition-colors hover:border-indigo-300 dark:hover:border-indigo-700/50 hover:bg-slate-50 dark:hover:bg-white/[0.04]"
704 >
705 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
706 {page.eyebrow}
707 </p>
708 <h4 className="mt-4 text-2xl font-semibold tracking-tight text-slate-900 transition-colors group-hover:text-indigo-600 dark:text-white dark:group-hover:text-indigo-400">
709 {page.title}
710 </h4>
711 <p className="mt-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
712 {page.description}
713 </p>
714 <ul className="mt-5 space-y-3 text-sm leading-6 text-slate-500 dark:text-slate-400">
715 {page.bullets.map((bullet) => (
716 <li key={bullet} className="flex gap-3">
717 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
718 <span>{bullet}</span>
719 </li>
720 ))}
721 </ul>
722 <p className="mt-6 text-sm font-semibold text-indigo-600 dark:text-indigo-400">
723 Read comparison →
724 </p>
725 </Link>
726 ))}
727 </div>
728 </div>
729 </div>
730 </div>
731 </section>
732
733 <section className="px-6 py-16 lg:px-8">
734 <div className="mx-auto max-w-2xl">
735 <div className="relative overflow-hidden rounded-2xl bg-indigo-600 px-8 py-14 text-center shadow-2xl shadow-indigo-500/20">
736 <div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_at_top,rgba(255,255,255,0.1),transparent)]" />
737 <h2 className="relative text-3xl font-bold tracking-tight text-white">
738 Try it on one app.
739 </h2>
740 <p className="relative mt-4 text-indigo-200">
741 Create an account and install the CLI.
742 </p>
743 <div className="relative mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
744 <Link
745 href="https://console.smbcloud.xyz"
746 target="_blank"
747 rel="noopener noreferrer"
748 className="inline-flex rounded-lg bg-white px-8 py-3.5 text-sm font-semibold text-indigo-700 shadow-sm transition-colors hover:bg-indigo-50"
749 >
750 Create free account →
751 </Link>
752 <Link
753 href="/services"
754 className="inline-flex rounded-lg border border-white/20 px-8 py-3.5 text-sm font-semibold text-white transition-colors hover:bg-white/10"
755 >
756 Explore services
757 </Link>
758 </div>
759 </div>
760 </div>
761 </section>
762
763 {publishedPosts.length > 0 && (
764 <section className="border-t border-slate-200 dark:border-white/[0.06] px-6 py-24 lg:px-8">
765 <div className="mx-auto max-w-5xl">
766 <div className="mb-10 flex items-end justify-between gap-4">
767 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
768 From the blog
769 </p>
770 <Link
771 href="/posts"
772 className="text-sm font-semibold text-indigo-600 transition-colors hover:text-indigo-500 dark:text-indigo-400"
773 >
774 View all posts
775 </Link>
776 </div>
777 <div className="space-y-6">
778 {publishedPosts.slice(0, 3).map((post) => (
779 <article
780 key={post._id}
781 className="group border-b border-slate-200 dark:border-white/[0.06] pb-6 last:border-0"
782 >
783 <Link href={post.slug} className="block">
784 <h3 className="font-semibold text-slate-900 dark:text-white transition-colors group-hover:text-indigo-600 dark:group-hover:text-indigo-400">
785 {post.title}
786 </h3>
787 {post.description && (
788 <p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
789 {post.description}
790 </p>
791 )}
792 </Link>
793 </article>
794 ))}
795 </div>
796 </div>
797 </section>
798 )}
799
800 <section className="px-6 pb-16 lg:px-8">
801 <div className="mx-auto max-w-2xl">
802 <div className="relative overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 px-8 py-12 dark:border-white/[0.08] dark:bg-white/[0.04]">
803 <div className="pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/20 to-transparent" />
804
805 <p className="mb-5 text-xs font-bold uppercase tracking-[0.2em] text-slate-500">
806 Also from smbCloud
807 </p>
808
809 <div className="mb-4 flex items-center gap-3">
810 <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-white text-slate-900">
811 <span className="text-xs font-black tracking-tighter leading-none">
812 si
813 </span>
814 </div>
815 <h2 className="text-2xl font-bold tracking-tight text-white">
816 siGit Code & Deploy
817 </h2>
818 </div>
819
820 <p className="mb-2 max-w-md text-sm leading-relaxed text-slate-300 dark:text-slate-400">
821 <span className="font-semibold text-white">smbcloud-cli</span> as
822 a native app. Review changes, edit, and deploy from your phone.
823 </p>
824 <p className="mb-8 text-xs italic text-slate-500">
825 Available on iPhone, Android, and Windows.
826 </p>
827
828 <div className="flex flex-wrap gap-3">
829 <a
830 href="https://apps.apple.com/se/app/sigit-git-client-code-editor/id6753018849"
831 target="_blank"
832 rel="noopener noreferrer"
833 className="inline-flex items-center gap-2 rounded-lg border border-white/20 bg-white/10 px-4 py-2.5 text-xs font-semibold text-white transition-colors hover:bg-white/20"
834 >
835 <FaApple className="h-4 w-4" />
836 App Store
837 </a>
838 <a
839 href="https://play.google.com/store/apps/details?id=xyz.smbcloud.SiGit"
840 target="_blank"
841 rel="noopener noreferrer"
842 className="inline-flex items-center gap-2 rounded-lg border border-white/20 bg-white/10 px-4 py-2.5 text-xs font-semibold text-white transition-colors hover:bg-white/20"
843 >
844 <FaGooglePlay className="h-4 w-4" />
845 Google Play
846 </a>
847 <a
848 href="https://apps.microsoft.com/detail/xp9k321rf5mzsz?ocid=webpdpshare"
849 target="_blank"
850 rel="noopener noreferrer"
851 className="inline-flex items-center gap-2 rounded-lg border border-white/20 bg-white/10 px-4 py-2.5 text-xs font-semibold text-white transition-colors hover:bg-white/20"
852 >
853 <FaWindows className="h-4 w-4" />
854 Microsoft Store
855 </a>
856 </div>
857 </div>
858 </div>
859 </section>
860 </div>
861 );
862 }