@pylonsync/create-pylon 0.11.0 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/bin/create-pylon.js +1 -1
  2. package/package.json +1 -1
  3. package/templates/_root/AGENTS.md +31 -1
  4. package/templates/agency/AGENTS.md +1 -1
  5. package/templates/agency/app/(marketing)/contact-form.tsx +22 -32
  6. package/templates/agency/app/(marketing)/layout.tsx +36 -64
  7. package/templates/agency/app/(marketing)/not-found.tsx +6 -8
  8. package/templates/agency/app/(marketing)/page.tsx +93 -144
  9. package/templates/agency/app/(marketing)/work/[slug]/page.tsx +69 -71
  10. package/templates/agency/app/(marketing)/work/page.tsx +20 -17
  11. package/templates/agency/app/globals.css +15 -6
  12. package/templates/agency/app.ts +10 -0
  13. package/templates/agency/components/marketing.tsx +40 -104
  14. package/templates/agency/lib/site.config.ts +34 -52
  15. package/templates/agency/public/images/hero.jpg +0 -0
  16. package/templates/agency/public/images/team/claire-donovan.jpg +0 -0
  17. package/templates/agency/public/images/team/dana-okafor.jpg +0 -0
  18. package/templates/agency/public/images/team/marcus-lee.jpg +0 -0
  19. package/templates/agency/public/images/work/atlas-health.jpg +0 -0
  20. package/templates/agency/public/images/work/cohort.jpg +0 -0
  21. package/templates/agency/public/images/work/ledger.jpg +0 -0
  22. package/templates/agency/public/images/work/vela.jpg +0 -0
  23. package/templates/ai-chat/AGENTS.md +1 -1
  24. package/templates/ai-studio/AGENTS.md +1 -1
  25. package/templates/barebones/AGENTS.md +1 -1
  26. package/templates/chat/AGENTS.md +1 -1
  27. package/templates/consumer/AGENTS.md +1 -1
  28. package/templates/consumer/README.md +39 -23
  29. package/templates/consumer/app/(app)/explore/page.tsx +13 -0
  30. package/templates/consumer/app/(app)/layout.tsx +17 -0
  31. package/templates/consumer/app/(app)/p/[id]/page.tsx +13 -0
  32. package/templates/consumer/app/(app)/page.tsx +15 -0
  33. package/templates/consumer/app/(app)/u/[username]/page.tsx +14 -0
  34. package/templates/consumer/app/error.tsx +1 -1
  35. package/templates/consumer/app/globals.css +25 -0
  36. package/templates/consumer/app/layout.tsx +3 -10
  37. package/templates/consumer/app/llms.ts +10 -10
  38. package/templates/consumer/app/not-found.tsx +9 -22
  39. package/templates/consumer/app/robots.ts +3 -4
  40. package/templates/consumer/app/sitemap.ts +7 -21
  41. package/templates/consumer/app.ts +152 -33
  42. package/templates/consumer/components/social/app-chrome.tsx +109 -0
  43. package/templates/consumer/components/social/avatar.tsx +50 -0
  44. package/templates/consumer/components/social/comment-form.tsx +51 -0
  45. package/templates/consumer/components/social/create-post.tsx +155 -0
  46. package/templates/consumer/components/social/edit-profile.tsx +103 -0
  47. package/templates/consumer/components/social/explore-screen.tsx +23 -0
  48. package/templates/consumer/components/social/home-screen.tsx +161 -0
  49. package/templates/consumer/components/social/post-card.tsx +77 -0
  50. package/templates/consumer/components/social/post-grid.tsx +46 -0
  51. package/templates/consumer/components/social/post-parts.tsx +146 -0
  52. package/templates/consumer/components/social/post-screen.tsx +173 -0
  53. package/templates/consumer/components/social/profile-screen.tsx +146 -0
  54. package/templates/consumer/components/social/rich-text.tsx +22 -0
  55. package/templates/consumer/components/social/session.tsx +43 -0
  56. package/templates/consumer/components/social/use-social.ts +86 -0
  57. package/templates/consumer/functions/addComment.ts +27 -0
  58. package/templates/consumer/functions/createPost.ts +39 -0
  59. package/templates/consumer/functions/ensureProfile.ts +39 -0
  60. package/templates/consumer/functions/seedFeed.ts +38 -0
  61. package/templates/consumer/functions/updateProfile.ts +61 -0
  62. package/templates/consumer/lib/seed.ts +192 -0
  63. package/templates/consumer/lib/site.ts +6 -0
  64. package/templates/consumer/lib/social.ts +245 -0
  65. package/templates/consumer/tests/social.test.ts +157 -0
  66. package/templates/creator/AGENTS.md +1 -1
  67. package/templates/creator/app/(marketing)/layout.tsx +35 -69
  68. package/templates/creator/app/(marketing)/newsletter-signup.tsx +15 -26
  69. package/templates/creator/app/(marketing)/not-found.tsx +8 -6
  70. package/templates/creator/app/(marketing)/page.tsx +90 -106
  71. package/templates/creator/app/globals.css +14 -0
  72. package/templates/creator/app/layout.tsx +1 -0
  73. package/templates/creator/app.ts +10 -0
  74. package/templates/creator/components/marketing.tsx +28 -89
  75. package/templates/creator/lib/site.config.ts +51 -29
  76. package/templates/creator/public/images/headshot.jpg +0 -0
  77. package/templates/crm/AGENTS.md +1 -1
  78. package/templates/crm/lib/seed.ts +153 -21
  79. package/templates/directory/AGENTS.md +1 -1
  80. package/templates/directory/app/(marketing)/directory-browse.tsx +99 -137
  81. package/templates/directory/app/(marketing)/layout.tsx +37 -88
  82. package/templates/directory/app/(marketing)/not-found.tsx +11 -10
  83. package/templates/directory/app/(marketing)/page.tsx +12 -33
  84. package/templates/directory/app/(marketing)/submit/page.tsx +9 -10
  85. package/templates/directory/app/(marketing)/submit-form.tsx +26 -26
  86. package/templates/directory/app/globals.css +15 -4
  87. package/templates/directory/app.ts +10 -0
  88. package/templates/directory/components/marketing.tsx +27 -91
  89. package/templates/directory/lib/site.config.ts +13 -24
  90. package/templates/expo/mobile/apps/expo/README.md +1 -1
  91. package/templates/expo/mobile/apps/expo/package.json +55 -54
  92. package/templates/expo/mobile/apps/expo/src/entitlements.ts +24 -6
  93. package/templates/helpdesk/AGENTS.md +1 -1
  94. package/templates/helpdesk/lib/seed.ts +188 -104
  95. package/templates/inventory/AGENTS.md +1 -1
  96. package/templates/inventory/lib/seed.ts +175 -44
  97. package/templates/invoices/AGENTS.md +1 -1
  98. package/templates/invoices/lib/seed.ts +74 -89
  99. package/templates/local-service/AGENTS.md +1 -1
  100. package/templates/local-service/app/(marketing)/booking-widget.tsx +31 -31
  101. package/templates/local-service/app/(marketing)/layout.tsx +25 -37
  102. package/templates/local-service/app/(marketing)/not-found.tsx +4 -4
  103. package/templates/local-service/app/(marketing)/page.tsx +145 -139
  104. package/templates/local-service/app/globals.css +11 -0
  105. package/templates/local-service/app/layout.tsx +2 -0
  106. package/templates/local-service/app.ts +9 -0
  107. package/templates/local-service/components/marketing.tsx +14 -39
  108. package/templates/local-service/lib/site.config.ts +16 -23
  109. package/templates/local-service/public/images/hero.jpg +0 -0
  110. package/templates/marketplace/AGENTS.md +1 -1
  111. package/templates/marketplace/client/SellForm.tsx +2 -0
  112. package/templates/projects/AGENTS.md +1 -1
  113. package/templates/projects/lib/seed.ts +103 -32
  114. package/templates/restaurant/AGENTS.md +1 -1
  115. package/templates/restaurant/app/(marketing)/layout.tsx +26 -48
  116. package/templates/restaurant/app/(marketing)/page.tsx +146 -123
  117. package/templates/restaurant/app/globals.css +11 -0
  118. package/templates/restaurant/app/layout.tsx +1 -0
  119. package/templates/restaurant/app.ts +10 -0
  120. package/templates/restaurant/components/marketing.tsx +10 -0
  121. package/templates/restaurant/lib/site.config.ts +16 -14
  122. package/templates/restaurant/public/images/bar.jpg +0 -0
  123. package/templates/restaurant/public/images/branzino.jpg +0 -0
  124. package/templates/restaurant/public/images/hearth.jpg +0 -0
  125. package/templates/restaurant/public/images/hero.jpg +0 -0
  126. package/templates/saas/AGENTS.md +1 -1
  127. package/templates/shop/AGENTS.md +1 -1
  128. package/templates/shop/public/images/products/cedar-smoke.jpg +0 -0
  129. package/templates/shop/public/images/products/linen.jpg +0 -0
  130. package/templates/todo/AGENTS.md +1 -1
  131. package/templates/waitlist/AGENTS.md +1 -1
  132. package/templates/waitlist/app/(marketing)/layout.tsx +39 -85
  133. package/templates/waitlist/app/(marketing)/not-found.tsx +8 -9
  134. package/templates/waitlist/app/(marketing)/page.tsx +51 -86
  135. package/templates/waitlist/app/(marketing)/waitlist-hero.tsx +43 -83
  136. package/templates/waitlist/app/globals.css +23 -0
  137. package/templates/waitlist/app/layout.tsx +1 -0
  138. package/templates/waitlist/app.ts +18 -0
  139. package/templates/waitlist/components/marketing.tsx +67 -81
  140. package/templates/waitlist/lib/site.config.ts +52 -59
  141. package/templates/agency/app/not-found.tsx +0 -44
  142. package/templates/ai-chat/app/not-found.tsx +0 -44
  143. package/templates/ai-studio/app/not-found.tsx +0 -44
  144. package/templates/consumer/app/feed-client.tsx +0 -159
  145. package/templates/consumer/app/page.tsx +0 -27
  146. package/templates/consumer/functions/_keep.ts +0 -13
  147. package/templates/consumer/functions/seedPosts.ts +0 -56
  148. package/templates/consumer/tests/example.test.ts +0 -12
  149. package/templates/creator/app/not-found.tsx +0 -44
  150. package/templates/directory/app/not-found.tsx +0 -44
  151. package/templates/local-service/app/not-found.tsx +0 -44
  152. package/templates/restaurant/app/not-found.tsx +0 -44
  153. package/templates/shop/app/not-found.tsx +0 -44
  154. package/templates/waitlist/app/not-found.tsx +0 -44
@@ -147,6 +147,24 @@ const manifest = buildManifest({
147
147
  display: "swap",
148
148
  preload: true,
149
149
  }),
150
+ // Headlines and the product mock's window title.
151
+ font({
152
+ family: "Space Grotesk",
153
+ variable: "--font-display",
154
+ weights: ["500", "700"],
155
+ subsets: ["latin"],
156
+ display: "swap",
157
+ preload: true,
158
+ }),
159
+ // Small details: the launch date, the live count, the form hint.
160
+ font({
161
+ family: "JetBrains Mono",
162
+ variable: "--font-mono-ui",
163
+ weights: ["400", "500"],
164
+ subsets: ["latin"],
165
+ display: "swap",
166
+ preload: false,
167
+ }),
150
168
  ],
151
169
  routes: await discoverAppRoutes(),
152
170
  });
@@ -1,96 +1,82 @@
1
1
  import React from "react";
2
+ import type { Fact, MockRow } from "@/lib/site.config";
2
3
 
3
- // Reusable presentational pieces for the landing page. All server-rendered —
4
- // no client JS. Restyle here and the whole page follows. The brand accent
5
- // (`text-brand`, `bg-brand-soft`) comes from CSS vars set on <html> in
6
- // app/layout.tsx, which read lib/site.config.ts — so re-theming is one edit.
4
+ // Presentational pieces for the landing page. All server-rendered, no client
5
+ // JS. Colors come from CSS vars set on <html> in app/layout.tsx, which read
6
+ // lib/site.config.ts.
7
7
 
8
- // Shared container: a contained, centered column.
9
- export const WRAP = "mx-auto w-full max-w-3xl px-6";
8
+ // Shared container: the page is left-aligned inside a wide column.
9
+ export const WRAP = "mx-auto w-full max-w-6xl px-6";
10
10
 
11
- export function Eyebrow({ children }: { children: React.ReactNode }) {
11
+ // Three short facts in a row, a thin rule above each.
12
+ export function FactList({ items }: { items: Fact[] }) {
12
13
  return (
13
- <p className="font-mono text-[11px] font-semibold uppercase tracking-[0.14em] text-brand">
14
- {children}
15
- </p>
16
- );
17
- }
18
-
19
- // "New / Coming soon"-style pill for the hero.
20
- export function Badge({ children }: { children: React.ReactNode }) {
21
- return (
22
- <span className="inline-flex items-center gap-2 rounded-full border border-zinc-200 bg-white py-1 pl-1.5 pr-3 text-[13px] text-zinc-600 shadow-sm">
23
- <span className="inline-block size-1.5 rounded-full bg-brand" />
24
- {children}
25
- </span>
26
- );
27
- }
28
-
29
- export function Divider() {
30
- return (
31
- <div className={WRAP}>
32
- <div className="border-t border-zinc-200/70" />
33
- </div>
34
- );
35
- }
36
-
37
- export function SectionHead({
38
- eyebrow,
39
- title,
40
- body,
41
- }: {
42
- eyebrow: string;
43
- title: string;
44
- body?: string;
45
- }) {
46
- return (
47
- <div>
48
- <Eyebrow>{eyebrow}</Eyebrow>
49
- <h2 className="mt-4 text-balance text-2xl font-semibold leading-[1.15] tracking-[-0.02em] sm:text-3xl">
50
- {title}
51
- </h2>
52
- {body ? (
53
- <p className="mt-4 max-w-xl text-[15px] leading-relaxed text-zinc-500">
54
- {body}
55
- </p>
56
- ) : null}
57
- </div>
14
+ <ul className="grid gap-x-8 gap-y-10 sm:grid-cols-3">
15
+ {items.map((f) => (
16
+ <li key={f.title} className="border-t border-line pt-5">
17
+ <h3 className="font-display text-[17px] font-medium text-chalk">{f.title}</h3>
18
+ <p className="mt-2 text-[14px] leading-relaxed text-chalk-2">{f.body}</p>
19
+ </li>
20
+ ))}
21
+ </ul>
58
22
  );
59
23
  }
60
24
 
61
- // A grid of value props — icon + title + body.
62
- export function FeatureGrid({
63
- items,
25
+ // A product window drawn with divs: a title bar, a sidebar, and task rows.
26
+ // No screenshot. Content comes from `siteConfig.mock`.
27
+ export function ProductMock({
28
+ windowTitle,
29
+ sidebar,
30
+ activeSidebarIndex,
31
+ rows,
64
32
  }: {
65
- items: { title: string; body: string; icon?: string }[];
33
+ windowTitle: string;
34
+ sidebar: string[];
35
+ activeSidebarIndex: number;
36
+ rows: MockRow[];
66
37
  }) {
67
38
  return (
68
- <div className="grid gap-6 sm:grid-cols-3">
69
- {items.map((f) => (
70
- <div key={f.title}>
71
- {f.icon ? (
72
- <span className="flex size-9 items-center justify-center rounded-lg bg-brand-soft text-brand">
73
- {f.icon}
74
- </span>
75
- ) : null}
76
- <h3 className="mt-4 text-[15px] font-semibold text-zinc-900">
77
- {f.title}
78
- </h3>
79
- <p className="mt-2 text-[14px] leading-relaxed text-zinc-500">
80
- {f.body}
81
- </p>
39
+ <div
40
+ aria-hidden
41
+ className="overflow-hidden rounded-lg border border-line bg-paper text-[12px] text-chalk-2"
42
+ >
43
+ <div className="flex h-9 items-center gap-2 border-b border-line px-3">
44
+ <span className="size-2.5 rounded-full bg-line" />
45
+ <span className="size-2.5 rounded-full bg-line" />
46
+ <span className="size-2.5 rounded-full bg-line" />
47
+ <span className="ml-3 font-display text-[12px] font-medium text-chalk">{windowTitle}</span>
48
+ </div>
49
+ <div className="grid grid-cols-[112px_1fr] sm:grid-cols-[140px_1fr]">
50
+ <div className="border-r border-line py-2">
51
+ {sidebar.map((item, i) => (
52
+ <div
53
+ key={item}
54
+ className={
55
+ i === activeSidebarIndex
56
+ ? "mx-2 rounded-md bg-ink-2 px-2 py-1.5 text-chalk"
57
+ : "mx-2 px-2 py-1.5"
58
+ }
59
+ >
60
+ {item}
61
+ </div>
62
+ ))}
82
63
  </div>
83
- ))}
64
+ <div className="divide-y divide-line">
65
+ {rows.map((r) => (
66
+ <div key={r.title} className="flex items-center gap-3 px-3 py-2.5">
67
+ <span
68
+ className={
69
+ r.done
70
+ ? "size-3.5 shrink-0 rounded-sm bg-brand"
71
+ : "size-3.5 shrink-0 rounded-sm border border-chalk-2/60"
72
+ }
73
+ />
74
+ <span className={r.done ? "text-chalk-2 line-through" : "text-chalk"}>{r.title}</span>
75
+ <span className="ml-auto font-mono-ui text-[11px] text-chalk-2">{r.tag}</span>
76
+ </div>
77
+ ))}
78
+ </div>
79
+ </div>
84
80
  </div>
85
81
  );
86
82
  }
87
-
88
- // Initials for testimonial avatars, so the cards look finished without a photo.
89
- export function initials(name: string) {
90
- return name
91
- .split(/\s+/)
92
- .map((w) => w[0])
93
- .join("")
94
- .slice(0, 2)
95
- .toUpperCase();
96
- }
@@ -22,21 +22,26 @@ export type BaseConfig = {
22
22
  socials: Social[];
23
23
  };
24
24
  // Marketing accent + surfaces. Applied as CSS vars on <html> in layout.tsx.
25
- colors: { brand: string; brandSoft: string; paper: string };
25
+ // `ink` is the page background, `paper` the raised panel color, `brand` the
26
+ // one accent, `brandSoft` the accent's dim fill.
27
+ colors: { brand: string; brandSoft: string; paper: string; ink: string };
26
28
  seo: { title: string; description: string };
27
29
  };
28
30
 
29
- export type ValueProp = { title: string; body: string; icon?: string };
30
- export type Quote = { quote: string; name: string; role: string };
31
+ export type Fact = { title: string; body: string };
31
32
  export type Faq = { q: string; a: string };
32
33
 
34
+ // A row in the product mock (a task or a note), drawn with plain divs.
35
+ export type MockRow = { title: string; tag: string; done?: boolean };
36
+
33
37
  export type WaitlistConfig = BaseConfig & {
34
38
  hero: {
35
- badge: string;
39
+ launchNote: string; // one short line, set in mono: when it ships
36
40
  headline: string;
37
41
  subcopy: string;
38
42
  emailPlaceholder: string;
39
43
  ctaLabel: string;
44
+ formHint: string;
40
45
  successMessage: string;
41
46
  };
42
47
  counter: {
@@ -46,13 +51,15 @@ export type WaitlistConfig = BaseConfig & {
46
51
  // page doesn't read "0". Set to 0 to show only genuine signups.
47
52
  seedCount?: number;
48
53
  };
49
- valueProps: { eyebrow: string; headline: string; items: ValueProp[] };
50
- socialProof?: {
51
- label: string;
52
- logos?: string[];
53
- quotes?: Quote[];
54
+ // The HTML/CSS product window on the right of the hero. No screenshot.
55
+ mock: {
56
+ windowTitle: string;
57
+ sidebar: string[];
58
+ activeSidebarIndex: number;
59
+ rows: MockRow[];
54
60
  };
55
- faq?: { eyebrow: string; headline: string; items: Faq[] };
61
+ facts: { headline: string; items: Fact[] };
62
+ faq?: { headline: string; items: Faq[] };
56
63
  };
57
64
 
58
65
  /* ----------------------------- config ---------------------------- */
@@ -64,7 +71,7 @@ export const siteConfig: WaitlistConfig = {
64
71
  domain: "lumo.app",
65
72
  email: "hello@lumo.example",
66
73
  footerBlurb:
67
- "Lumo keeps projects, notes, and tasks in one focused workspace. Join the list for an early invite.",
74
+ "Lumo keeps projects, notes, and tasks in one workspace. Join the list for an early invite.",
68
75
  copyrightName: "Lumo, Inc.",
69
76
  socials: [
70
77
  {
@@ -80,95 +87,81 @@ export const siteConfig: WaitlistConfig = {
80
87
  ],
81
88
  },
82
89
 
83
- colors: { brand: "#4f46e5", brandSoft: "#eef2ff", paper: "#fafafa" },
90
+ // Near-black page, one electric blue accent.
91
+ colors: { brand: "#4f6bff", brandSoft: "#141a3d", paper: "#121214", ink: "#0b0b0c" },
84
92
 
85
93
  seo: {
86
- title: "Lumo — the calm home for your work. Coming soon.",
94
+ title: "Lumo — projects, notes, and tasks in one workspace. Coming soon.",
87
95
  description:
88
- "Lumo brings your projects, notes, and tasks into one quiet, focused space. We're launching soon — join the waitlist for an early invite.",
96
+ "Lumo puts your projects, notes, and tasks in one workspace. It launches this fall. Join the waitlist for an early invite.",
89
97
  },
90
98
 
91
99
  hero: {
92
- badge: "Launching this fall",
93
- headline: "Projects, notes, and tasks in one calm place.",
100
+ launchNote: "Launch: fall 2026",
101
+ headline: "Projects, notes, and tasks in one workspace.",
94
102
  subcopy:
95
- "Lumo keeps your projects, notes, and tasks together in a focused workspace. Join the list for an early invite.",
103
+ "Lumo is one app for the plan, the notes behind it, and the tasks that come out of it. Join the list and we send an invite before the public launch.",
96
104
  emailPlaceholder: "you@work.com",
97
105
  ctaLabel: "Join the waitlist",
98
- successMessage: "You're on the list — we'll email your invite soon.",
106
+ formHint: "One invite email. No newsletter.",
107
+ successMessage: "You are on the list. We will email your invite.",
99
108
  },
100
109
 
101
110
  counter: {
102
111
  enabled: true,
103
- label: "people already waiting",
112
+ label: "people on the list",
104
113
  seedCount: 1200,
105
114
  },
106
115
 
107
- valueProps: {
108
- eyebrow: "Why Lumo",
109
- headline: "Keep your attention on the work.",
110
- items: [
111
- {
112
- icon: "◇",
113
- title: "One quiet space",
114
- body: "Projects, notes, and tasks live together — so nothing gets lost between five different apps.",
115
- },
116
- {
117
- icon: "◎",
118
- title: "For people who make things",
119
- body: "Designers, founders, writers, builders. If your work needs deep focus, Lumo is built for you.",
120
- },
121
- {
122
- icon: "✦",
123
- title: "Calm by default",
124
- body: "Lumo keeps notifications and feeds quiet, then shows the work that needs attention now.",
125
- },
116
+ mock: {
117
+ windowTitle: "Site redesign",
118
+ sidebar: ["Inbox", "Site redesign", "Q4 plan", "Reading", "Archive"],
119
+ activeSidebarIndex: 1,
120
+ rows: [
121
+ { title: "Draft the homepage copy", tag: "Today", done: true },
122
+ { title: "Review nav on mobile", tag: "Today" },
123
+ { title: "Pick the display face", tag: "Note" },
124
+ { title: "Send pricing page to Priya", tag: "Tomorrow" },
125
+ { title: "Set up the launch checklist", tag: "Next week" },
126
126
  ],
127
127
  },
128
128
 
129
- socialProof: {
130
- label: "Loved by early testers",
131
- quotes: [
129
+ facts: {
130
+ headline: "What Lumo does",
131
+ items: [
132
132
  {
133
- quote:
134
- "I've tried every productivity app out there. Lumo is the first one that leaves me calmer after planning my week.",
135
- name: "Maya Chen",
136
- role: "Product designer",
133
+ title: "One place for a project",
134
+ body: "Each project holds its plan, its notes, and its tasks. Nothing lives in a second app.",
137
135
  },
138
136
  {
139
- quote:
140
- "All my half-finished projects are in one place. I check it every morning and know what to do next.",
141
- name: "Daniel Reyes",
142
- role: "Indie founder",
137
+ title: "Notes turn into tasks",
138
+ body: "Select a line in a note and make it a task. The task keeps a link back to the note.",
143
139
  },
144
140
  {
145
- quote:
146
- "It's fast, it's quiet, and it stays out of my way. I joined the waitlist the day I saw the first demo.",
147
- name: "Hannah Brooks",
148
- role: "Writer",
141
+ title: "No feed, no badges",
142
+ body: "Lumo has no activity feed. You see the tasks due today and the project you opened last.",
149
143
  },
150
144
  ],
151
145
  },
152
146
 
153
147
  faq: {
154
- eyebrow: "Questions",
155
- headline: "Good to know.",
148
+ headline: "Questions",
156
149
  items: [
157
150
  {
158
151
  q: "When does Lumo launch?",
159
- a: "We're aiming for this fall. Waitlist members get an invite before the public launch.",
152
+ a: "Fall 2026. People on the waitlist get an invite before the public launch.",
160
153
  },
161
154
  {
162
155
  q: "What do I get for joining?",
163
- a: "An early invite, founding-member pricing, and a direct line to shape what we build next.",
156
+ a: "An early invite and founding-member pricing on paid plans.",
164
157
  },
165
158
  {
166
159
  q: "How much will it cost?",
167
- a: "There'll be a generous free tier. Waitlist members lock in founding-member pricing on paid plans.",
160
+ a: "There is a free tier. Paid plans are priced at launch. Waitlist members keep the founding-member price.",
168
161
  },
169
162
  {
170
163
  q: "Will my email be shared?",
171
- a: "Never. We only use it to send your invite and the occasional launch update. Unsubscribe anytime.",
164
+ a: "No. We use it for the invite and launch updates only. You can unsubscribe at any time.",
172
165
  },
173
166
  ],
174
167
  },
@@ -1,44 +0,0 @@
1
- import React from "react";
2
- import { Link, type NotFoundProps } from "@pylonsync/react";
3
- import { Button } from "@/components/ui/button";
4
-
5
- // `app/not-found.tsx` → rendered at HTTP 404 for any unmatched URL, and when a
6
- // page calls `response.notFound()`.
7
- //
8
- // Give it real links. This boundary is also what an agent reads when it guesses
9
- // a URL wrong: a markdown request for a missing page renders THIS file as
10
- // markdown at 404, so the links below are how it finds its way back.
11
- export default function NotFound(_props: NotFoundProps) {
12
- return (
13
- <div className="mx-auto flex min-h-[60vh] max-w-lg flex-col justify-center gap-6 px-4">
14
- <section>
15
- <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
16
- <p className="mt-2 text-muted-foreground">
17
- That URL does not exist. Try one of these:
18
- </p>
19
- </section>
20
- <ul className="space-y-2 text-sm">
21
- <li>
22
- <Link className="underline underline-offset-4" href="/">
23
- Home
24
- </Link>
25
- </li>
26
- <li>
27
- <a className="underline underline-offset-4" href="/sitemap.xml">
28
- Sitemap
29
- </a>
30
- </li>
31
- <li>
32
- <a className="underline underline-offset-4" href="/llms.txt">
33
- llms.txt
34
- </a>
35
- </li>
36
- </ul>
37
- <div>
38
- <Button asChild>
39
- <Link href="/">Back to home</Link>
40
- </Button>
41
- </div>
42
- </div>
43
- );
44
- }
@@ -1,44 +0,0 @@
1
- import React from "react";
2
- import { Link, type NotFoundProps } from "@pylonsync/react";
3
- import { Button } from "@/components/ui/button";
4
-
5
- // `app/not-found.tsx` → rendered at HTTP 404 for any unmatched URL, and when a
6
- // page calls `response.notFound()`.
7
- //
8
- // Give it real links. This boundary is also what an agent reads when it guesses
9
- // a URL wrong: a markdown request for a missing page renders THIS file as
10
- // markdown at 404, so the links below are how it finds its way back.
11
- export default function NotFound(_props: NotFoundProps) {
12
- return (
13
- <div className="mx-auto flex min-h-[60vh] max-w-lg flex-col justify-center gap-6 px-4">
14
- <section>
15
- <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
16
- <p className="mt-2 text-muted-foreground">
17
- That URL does not exist. Try one of these:
18
- </p>
19
- </section>
20
- <ul className="space-y-2 text-sm">
21
- <li>
22
- <Link className="underline underline-offset-4" href="/">
23
- Home
24
- </Link>
25
- </li>
26
- <li>
27
- <a className="underline underline-offset-4" href="/sitemap.xml">
28
- Sitemap
29
- </a>
30
- </li>
31
- <li>
32
- <a className="underline underline-offset-4" href="/llms.txt">
33
- llms.txt
34
- </a>
35
- </li>
36
- </ul>
37
- <div>
38
- <Button asChild>
39
- <Link href="/">Back to home</Link>
40
- </Button>
41
- </div>
42
- </div>
43
- );
44
- }
@@ -1,44 +0,0 @@
1
- import React from "react";
2
- import { Link, type NotFoundProps } from "@pylonsync/react";
3
- import { Button } from "@/components/ui/button";
4
-
5
- // `app/not-found.tsx` → rendered at HTTP 404 for any unmatched URL, and when a
6
- // page calls `response.notFound()`.
7
- //
8
- // Give it real links. This boundary is also what an agent reads when it guesses
9
- // a URL wrong: a markdown request for a missing page renders THIS file as
10
- // markdown at 404, so the links below are how it finds its way back.
11
- export default function NotFound(_props: NotFoundProps) {
12
- return (
13
- <div className="mx-auto flex min-h-[60vh] max-w-lg flex-col justify-center gap-6 px-4">
14
- <section>
15
- <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
16
- <p className="mt-2 text-muted-foreground">
17
- That URL does not exist. Try one of these:
18
- </p>
19
- </section>
20
- <ul className="space-y-2 text-sm">
21
- <li>
22
- <Link className="underline underline-offset-4" href="/">
23
- Home
24
- </Link>
25
- </li>
26
- <li>
27
- <a className="underline underline-offset-4" href="/sitemap.xml">
28
- Sitemap
29
- </a>
30
- </li>
31
- <li>
32
- <a className="underline underline-offset-4" href="/llms.txt">
33
- llms.txt
34
- </a>
35
- </li>
36
- </ul>
37
- <div>
38
- <Button asChild>
39
- <Link href="/">Back to home</Link>
40
- </Button>
41
- </div>
42
- </div>
43
- );
44
- }