main
tsx 144 lines 5.25 KB
Raw
1 import { TunnelCommandForm } from "@/components/TunnelCommandForm";
2
3 const coreFeatures = [
4 {
5 eyebrow: "Ingress",
6 title: "Public HTTPS for localhost",
7 description:
8 "Publish local services through public relays without opening inbound ports.",
9 },
10 {
11 eyebrow: "TLS",
12 title: "Keyless end-to-end tenant TLS",
13 description:
14 "Relays sign handshakes without session keys; ECH hides SNI and self-probes flag suspected MITM.",
15 },
16 {
17 eyebrow: "Relays",
18 title: "Self-hosted anonymous relays",
19 description:
20 "Use discovered public relays or run your own without a central account or operator.",
21 },
22 {
23 eyebrow: "Multi-hop",
24 title: "Multihop Routing (like Tor)",
25 description:
26 "Route through multiple relays so each hop sees only its neighbors, not the full path.",
27 },
28 {
29 eyebrow: "Payments",
30 title: "x402 for the agentic web",
31 description:
32 "Agents and browsers pay with Sui USDC in-flow; the tunnel enforces access to protected routes.",
33 },
34 {
35 eyebrow: "Transport",
36 title: "Web traffic and raw protocols",
37 description:
38 "Carry HTTPS, raw TCP, and UDP workloads without SSH or WebSocket overlays.",
39 },
40 ] as const;
41
42 export function LandingHero() {
43 return (
44 <section
45 aria-labelledby="landing-title"
46 className="relative pt-10 sm:pt-12 lg:pt-14"
47 >
48 <div aria-hidden="true" className="pointer-events-none absolute inset-0">
49 <div
50 className="absolute inset-0 opacity-45 bg-size-[14px_14px] mask-[linear-gradient(to_bottom,white,transparent_80%)]"
51 style={{
52 backgroundImage:
53 "radial-gradient(var(--hero-grid-dot) 0.8px, transparent 0.8px)",
54 }}
55 />
56 </div>
57
58 <a
59 href="#live-servers"
60 className="sr-only focus:not-sr-only focus:absolute focus:left-6 focus:top-6 focus:z-20 focus:rounded-md focus:bg-background focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-foreground"
61 >
62 Skip to live servers
63 </a>
64
65 <div className="relative mx-auto max-w-6xl">
66 <div className="mx-auto max-w-4xl text-center">
67 <h1
68 id="landing-title"
69 className="text-4xl font-extrabold tracking-normal text-foreground sm:text-5xl lg:text-7xl"
70 style={{ lineHeight: 0.96 }}
71 >
72 <span className="block">Expose Local Apps</span>
73 <span className="mt-2 block text-primary">
74 To The Public Internet
75 </span>
76 </h1>
77 <p className="mx-auto mt-5 max-w-2xl text-base leading-7 text-text-muted sm:text-lg">
78 Use relays as the public edge while your tunnel remains the app
79 endpoint and owns routing behavior.
80 </p>
81 </div>
82
83 <div id="quick-start" className="relative mt-9 scroll-mt-24 sm:mt-10">
84 <div
85 className="relative mx-auto w-full max-w-150 rounded-lg border px-4 py-5 sm:px-5 sm:py-6"
86 style={{
87 background: "var(--hero-terminal-bg)",
88 borderColor: "var(--hero-terminal-border)",
89 color: "var(--hero-terminal-foreground)",
90 boxShadow: "0 18px 44px var(--hero-terminal-shadow)",
91 }}
92 >
93 <div className="mb-5 flex min-w-0 items-center justify-between gap-3">
94 <div className="flex min-w-0 items-center gap-3">
95 <span
96 aria-hidden="true"
97 className="shrink-0 font-mono text-lg leading-none"
98 style={{ color: "var(--hero-terminal-accent)" }}
99 >
100 {">"}
101 </span>
102 <h2
103 id="tunnel-preview"
104 className="min-w-0 text-xl font-bold tracking-normal sm:text-2xl"
105 >
106 Start a tunnel
107 </h2>
108 </div>
109 </div>
110 <TunnelCommandForm theme="terminal" mode="hero" />
111 </div>
112 </div>
113 </div>
114
115 <div className="relative mt-10 -mx-4 w-auto sm:-mx-6 md:-mx-8">
116 <div className="overflow-hidden border-y border-border/80 bg-border/80">
117 <div className="grid gap-px sm:grid-cols-2 lg:grid-cols-3">
118 {coreFeatures.map(({ eyebrow, title, description }) => (
119 <article
120 key={title}
121 className="flex min-h-48 bg-background p-6 text-left transition-colors duration-200 hover:bg-secondary/35 sm:min-h-52 sm:p-7"
122 >
123 <div className="flex h-full flex-col space-y-3">
124 <p className="text-[11px] font-semibold uppercase tracking-normal text-primary/80">
125 {eyebrow}
126 </p>
127 <h3 className="text-[1.2rem] font-semibold tracking-normal text-foreground sm:text-[1.32rem] sm:leading-tight">
128 {title}
129 </h3>
130 <p className="max-w-[30ch] text-[0.95rem] leading-6 text-text-muted">
131 {description}
132 </p>
133 <div className="mt-auto pt-4">
134 <div className="h-px w-10 bg-primary/45" />
135 </div>
136 </div>
137 </article>
138 ))}
139 </div>
140 </div>
141 </div>
142 </section>
143 );
144 }