Skip to content

Commit 3c2b9b4

Browse files
committed
feat: use CMS for all of the tet
1 parent 013be03 commit 3c2b9b4

9 files changed

Lines changed: 229 additions & 98 deletions

File tree

website/astro.config.mjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,10 @@ export default defineConfig({
2828
},
2929
],
3030
},
31-
integrations: [mdx(), keystatic(), react(), icon()],
31+
integrations: [
32+
mdx(),
33+
...(process.env.SKIP_KEYSTATIC ? [] : [keystatic()]),
34+
react(),
35+
icon(),
36+
],
3237
});

website/keystatic.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default config({
55
storage: {
66
kind: "local",
77
},
8-
8+
locale: "en-US",
99
collections: {
1010
posts: collection({
1111
label: "Posts",

website/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@
2222
"react-dom": "^19.1.0",
2323
"tailwindcss": "^4.1.8",
2424
"tiny-invariant": "^1.3.3"
25+
},
26+
"devDependencies": {
27+
"@iconify-json/bi": "^1.2.4",
28+
"@iconify-json/simple-icons": "^1.2.38"
2529
}
2630
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,43 @@
11
openGraph:
22
title: Threshold Security
3+
description: building the best infrastructure for decentralized multisigs
34
type: website
45
publishedTime: 2025-06-10
56
modifiedTime: 2025-06-10
67
author: skeptrune
78
primaryCategory: about
89
actions: []
10+
waitlist:
11+
label: join waitlist
12+
description: Get updates on our progress and be the first to know when we launch.
13+
inputPlaceholder: your@email.com
14+
buttonText: join waitlist
15+
numberSuffix: people waiting
16+
roadmap:
17+
label: roadmap
18+
items:
19+
- label: DKG
20+
description: >-
21+
interactive key generation ceremony for up to 256 participants including
22+
integration tests
23+
status: in progress
24+
- label: deposits
25+
description: >-
26+
RPC route, rocksdb-backed storage, and business logic for tracking new
27+
deposits and increasing balance of the depositor
28+
status: in progress
29+
- label: withdrawals
30+
description: >-
31+
RPC route, fee calculation, UTXO management, and signature validation
32+
for withdrawing from a given account balance
33+
status: not started
34+
- label: tendermint
35+
description: >-
36+
business logic for handling staking, slashing, and unbonding of the
37+
validator set, including integration tests
38+
status: not started
39+
- label: member rotation
40+
description: >-
41+
epoch-based member rotation with sweeping of funds from one set of
42+
members to another, including integration tests
43+
status: not started

website/src/layouts/HomeLayout.astro

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
---
22
import "../styles/global.css";
33
import { ClientRouter } from "astro:transitions";
4-
import { SiteName } from "../theme.config";
4+
import { SiteName, SocialLinks } from "../theme.config";
55
import { Font } from "astro:assets";
6+
import { Icon } from "astro-icon/components";
67
78
const {
89
title = "Default Title",
@@ -78,22 +79,40 @@ const currentPath = Astro.url.pathname;
7879
<h1
7980
class="text-4xl md:text-6xl font-bold mb-4 border-b-2 sm:pb-6 pb-3 border-brand-500"
8081
>
81-
Threshold Security
82+
{title}
8283
</h1>
8384
<p class="text-sm md:text-base text-btcgray-600">
84-
infrastructure for decentralized multisigs
85+
{description}
8586
</p>
8687
</header>
8788
<main>
8889
<slot />
8990
</main>
9091
<footer
91-
class="mt-16 text-center text-sm text-btcgray-600 pt-8 border-t border-btcgray-50 w-full"
92+
class="mt-16 text-center text-sm text-btcgray-600 pt-8 border-t border-btcgray-50 w-full flex justify-between"
9293
>
94+
<ul class="flex items-center space-x-4">
95+
{
96+
SocialLinks.map((link) => (
97+
<li>
98+
<a
99+
href={link.href}
100+
target="_blank"
101+
rel="noopener noreferrer"
102+
class="icon hover:text-brand-500 transition-colors"
103+
aria-label={link.icon.split(":")[1]}
104+
>
105+
<Icon name={link.icon} />
106+
</a>
107+
</li>
108+
))
109+
}
110+
</ul>
93111
<p>
94-
&copy; 2025 athas code editor &mdash; <a
95-
href="#"
96-
class="border-b-2 border-brand-500 font-bold">@athasdev</a
112+
email us &mdash; <a
113+
href="mailto:team@onthreshold.com"
114+
class="border-b-2 border-brand-500 font-bold"
115+
>team@onthreshold.com</a
97116
>
98117
</p>
99118
</footer>
Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
11
import { fields } from "@keystatic/core";
22

3-
export const action = fields.object({
4-
label: fields.text({
5-
label: "Label",
6-
validation: {
7-
isRequired: true,
8-
},
9-
}),
10-
href: fields.text({
11-
label: "URL",
12-
validation: {
13-
isRequired: true,
14-
},
15-
}),
16-
newTab: fields.checkbox({
17-
label: "Open in new tab",
18-
}),
19-
variant: fields.select({
20-
label: "Variant",
21-
description: "The style variant of the button",
22-
options: [
23-
{ value: "primary", label: "Primary" },
24-
{ value: "secondary", label: "Secondary" },
25-
],
26-
defaultValue: "secondary",
27-
}),
28-
});
3+
export const action = fields.object(
4+
{
5+
label: fields.text({
6+
label: "Label",
7+
validation: {
8+
isRequired: true,
9+
},
10+
}),
11+
href: fields.text({
12+
label: "URL",
13+
validation: {
14+
isRequired: true,
15+
},
16+
}),
17+
newTab: fields.checkbox({
18+
label: "Open in new tab",
19+
}),
20+
variant: fields.select({
21+
label: "Variant",
22+
description: "The style variant of the button",
23+
options: [
24+
{ value: "primary", label: "Primary" },
25+
{ value: "secondary", label: "Secondary" },
26+
],
27+
defaultValue: "secondary",
28+
}),
29+
},
30+
{
31+
label: "Action",
32+
description:
33+
"An action button that can link to an external URL or internal page.",
34+
}
35+
);

website/src/lib/keystatic/singletons/homepage.ts

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,89 @@ export const homepage = singleton({
77
path: "src/content/singles/homepage/",
88
schema: {
99
openGraph: opengraph,
10-
actions: fields.array(action),
10+
actions: fields.array(action, {
11+
label: "Actions",
12+
description: "A list of action buttons for the homepage.",
13+
}),
14+
waitlist: fields.object(
15+
{
16+
label: fields.text({
17+
label: "Waitlist Label",
18+
description: "The label for the waitlist section on the homepage.",
19+
defaultValue: "join waitlist",
20+
}),
21+
description: fields.text({
22+
label: "Waitlist Description",
23+
description: "A brief description for the waitlist section.",
24+
defaultValue:
25+
"Get updates on our progress and be the first to know when we launch.",
26+
}),
27+
inputPlaceholder: fields.text({
28+
label: "Waitlist Input Placeholder",
29+
description: "Placeholder text for the waitlist input field.",
30+
defaultValue: "your@email.com",
31+
}),
32+
buttonText: fields.text({
33+
label: "Waitlist Button Text",
34+
description: "The text for the waitlist button on the homepage.",
35+
defaultValue: "join waitlist",
36+
}),
37+
numberSuffix: fields.text({
38+
label: "Waitlist Number Suffix",
39+
description:
40+
"The suffix for the waitlist number displayed on the homepage.",
41+
defaultValue: "people waiting",
42+
}),
43+
},
44+
{
45+
label: "Waitlist Section",
46+
description: "Configuration for the homepage waitlist section.",
47+
}
48+
),
49+
roadmap: fields.object(
50+
{
51+
label: fields.text({
52+
label: "Roadmap Title",
53+
description: "The title for the homepage roadmap section.",
54+
defaultValue: "roadmap",
55+
}),
56+
items: fields.array(
57+
fields.object(
58+
{
59+
label: fields.text({
60+
label: "Label",
61+
description: "The label for the roadmap item.",
62+
}),
63+
description: fields.text({
64+
label: "Description",
65+
description: "A brief description of the roadmap item.",
66+
}),
67+
status: fields.select({
68+
label: "Status",
69+
description: "The current status of the roadmap item.",
70+
options: [
71+
{ value: "not started", label: "Not Started" },
72+
{ value: "in progress", label: "In Progress" },
73+
{ value: "completed", label: "Completed" },
74+
],
75+
defaultValue: "not started",
76+
}),
77+
},
78+
{
79+
label: "Roadmap Item",
80+
description: "An item in the homepage roadmap section.",
81+
}
82+
),
83+
{
84+
label: "Roadmap Items",
85+
description: "A list of items for the homepage roadmap section.",
86+
}
87+
),
88+
},
89+
{
90+
label: "Roadmap Section",
91+
description: "Configuration for the homepage roadmap section.",
92+
}
93+
),
1194
},
1295
});

website/src/pages/index.astro

Lines changed: 25 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -22,88 +22,52 @@ invariant(i18n, "No homepage content found");
2222
<div class="flex flex-col md:flex-row gap-16 w-full max-w-4xl">
2323
<section class="flex-1">
2424
<h2 class="text-2xl font-semibold mb-4 border-l-4 border-brand-500 pl-4">
25-
join waitlist
25+
{i18n.waitlist.label}
2626
</h2>
2727
<p class="mb-4 text-btcgray-600">
28-
Get updates on our progress and be the first to know when we launch.
28+
{i18n.waitlist.description}
2929
</p>
3030
<form class="flex flex-col">
3131
<input
3232
type="email"
33-
placeholder="your@email.com"
33+
placeholder={i18n.waitlist.inputPlaceholder}
3434
class="border border-btcgray-300 p-3 rounded mb-4 focus:ring-2 focus:ring-brand-500 outline-none"
3535
/>
3636
<button
3737
type="submit"
3838
class="bg-btcgray-800 text-white p-3 rounded hover:bg-btcgray-700"
39-
>join waitlist</button
4039
>
40+
{i18n.waitlist.buttonText}
41+
</button>
4142
</form>
4243
<p class="mt-2 text-sm text-btcgray-600">
43-
&rarr; 1,070 developers waiting
44+
&rarr; 1,070 {i18n.waitlist.numberSuffix}
4445
</p>
4546
</section>
4647

4748
<section class="flex-1">
4849
<h2 class="text-2xl font-semibold mb-4 border-l-4 border-brand-500 pl-4">
49-
roadmap
50+
{i18n.roadmap.label}
5051
</h2>
5152
<ul class="space-y-4 w-full">
52-
<li class="flex items-start w-full">
53-
<span class="bg-brand-500 rounded-full w-3 h-3 mr-3 mt-1.5"></span>
54-
<div class="w-[93%]">
55-
<h3 class="font-semibold">DKG</h3>
56-
<p class="text-sm text-btcgray-600">
57-
interactive key generation ceremony for up to 256 participants
58-
including integration tests
59-
</p>
60-
<span class="text-xs text-btcgray-400">in progress</span>
61-
</div>
62-
</li>
63-
<li class="flex items-start">
64-
<span class="bg-brand-500 rounded-full w-3 h-3 mr-3 mt-1.5"></span>
65-
<div class="w-[93%]">
66-
<h3 class="font-semibold">deposits</h3>
67-
<p class="text-sm text-btcgray-600">
68-
RPC route, rocksdb-backed storage, and business logic for tracking
69-
new deposits and increasing balance of the depositor
70-
</p>
71-
<span class="text-xs text-btcgray-400">in progress</span>
72-
</div>
73-
</li>
74-
<li class="flex items-start">
75-
<span class="bg-btcgray-400 rounded-full w-3 h-3 mr-3 mt-1.5"></span>
76-
<div class="w-[93%]">
77-
<h3 class="font-semibold">withdrawals</h3>
78-
<p class="text-sm text-btcgray-600">
79-
RPC route, fee calculation, UTXO management, and signature
80-
validation for withdrawing from a given account balance
81-
</p>
82-
<span class="text-xs text-btcgray-400"> not started </span>
83-
</div>
84-
</li>
85-
<li class="flex items-start">
86-
<span class="bg-btcgray-400 rounded-full w-3 h-3 mr-3 mt-1.5"></span>
87-
<div class="w-[93%]">
88-
<h3 class="font-semibold">tendermint</h3>
89-
<p class="text-sm text-btcgray-600">
90-
business logic for handling staking, slashing, and unbonding of
91-
the validator set, including integration tests
92-
</p>
93-
<span class="text-xs text-btcgray-400">not started</span>
94-
</div>
95-
</li>
96-
<li class="flex items-start">
97-
<span class="bg-btcgray-400 rounded-full w-3 h-3 mr-3 mt-1.5"></span>
98-
<div class="w-[93%]">
99-
<h3 class="font-semibold">member rotation</h3>
100-
<p class="text-sm text-btcgray-600">
101-
epoch-based member rotation with sweeping of funds from one set of
102-
members to another, including integration tests
103-
</p>
104-
<span class="text-xs text-btcgray-400">not started</span>
105-
</div>
106-
</li>
53+
{
54+
i18n.roadmap.items.map((item) => (
55+
<li class="flex items-start">
56+
<span
57+
class={`rounded-full w-3 h-3 mr-3 mt-1.5 ${
58+
item.status === "in progress"
59+
? "bg-brand-500"
60+
: "bg-btcgray-400"
61+
}`}
62+
/>
63+
<div class="w-[93%]">
64+
<h3 class="font-semibold">{item.label}</h3>
65+
<p class="text-sm text-btcgray-600">{item.description}</p>
66+
<span class="text-xs text-btcgray-400">{item.status}</span>
67+
</div>
68+
</li>
69+
))
70+
}
10771
</ul>
10872
</section>
10973
</div>

0 commit comments

Comments
 (0)