+
+ {formattedDate}
+
+
+ {title}
+
{
- heroImage && (
-
-
+ !horizontal && tags.length > 0 && (
+
+ {tags.slice(0, 4).map((tag) => (
+
+ {t(`blog.tags.${tag}`) || tag}
+
+ ))}
)
}
-
-
- {formattedDate}
-
- {
- featured && (
-
- {t("blog.featured_label")}
-
- )
- }
-
-
- {title}
-
-
- {description}
-
-
- {
- tags.length > 0 && (
-
+ )
+ }
+
+
diff --git a/website/src/components/features/community/BlogSection.astro b/website/src/components/features/community/BlogSection.astro
new file mode 100644
index 0000000..9ac7225
--- /dev/null
+++ b/website/src/components/features/community/BlogSection.astro
@@ -0,0 +1,195 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
diff --git a/website/src/components/features/community/EventSection.astro b/website/src/components/features/community/EventSection.astro
new file mode 100644
index 0000000..0a10373
--- /dev/null
+++ b/website/src/components/features/community/EventSection.astro
@@ -0,0 +1,125 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+ {t("community.events.eyebrow")}
+
+
+ {t("community.events.heading")}
+
+
+
+
+
+ {t("community.events.card.status")}
+
+
+
+
+
+
+
diff --git a/website/src/components/features/community/HeroBanner.astro b/website/src/components/features/community/HeroBanner.astro
new file mode 100644
index 0000000..a0782ff
--- /dev/null
+++ b/website/src/components/features/community/HeroBanner.astro
@@ -0,0 +1,248 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/community/PodcastSection.astro b/website/src/components/features/community/PodcastSection.astro
new file mode 100644
index 0000000..e3c61d4
--- /dev/null
+++ b/website/src/components/features/community/PodcastSection.astro
@@ -0,0 +1,186 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+
{t("community.podcast.eyebrow")}
+
{t("community.podcast.heading")}
+
+ {t("community.podcast.body")}
+
+
+
+
+
+
+ {t("community.podcast.episode.title")}
+
+
+ {t("community.podcast.episode.meta")}
+
+
+
+
+
+
+
diff --git a/website/src/components/features/community/SocialsSection.astro b/website/src/components/features/community/SocialsSection.astro
new file mode 100644
index 0000000..9f15f29
--- /dev/null
+++ b/website/src/components/features/community/SocialsSection.astro
@@ -0,0 +1,128 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
{t("community.socials.eyebrow")}
+
+
+
+
+
diff --git a/website/src/components/features/community/TelegramSection.astro b/website/src/components/features/community/TelegramSection.astro
new file mode 100644
index 0000000..68a86c7
--- /dev/null
+++ b/website/src/components/features/community/TelegramSection.astro
@@ -0,0 +1,86 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+ {t("community.telegram.eyebrow")}
+
+
+ {t("community.telegram.heading")}
+
+
+ {t("community.telegram.body")}
+
+
{t("community.telegram.cta")}
+
+
+
+
diff --git a/website/src/components/features/contact/ContactForm.astro b/website/src/components/features/contact/ContactForm.astro
deleted file mode 100644
index d79907e..0000000
--- a/website/src/components/features/contact/ContactForm.astro
+++ /dev/null
@@ -1,127 +0,0 @@
----
-import Button from "@/components/ui/Button.astro";
-import Input from "@/components/ui/Input.astro";
-
-import { Image } from "astro:assets";
-import ContactImage from "@/assets/planet-like-object-with-ring.png";
-import TextArea from "@/components/ui/TextArea.astro";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
-
diff --git a/website/src/components/features/home/BlogSection.astro b/website/src/components/features/home/BlogSection.astro
new file mode 100644
index 0000000..a89f9fb
--- /dev/null
+++ b/website/src/components/features/home/BlogSection.astro
@@ -0,0 +1,530 @@
+
+
+
+
+
Latest from Quantus
+
Stay ahead of the quantum shift.
+
+
Blogs
+
+
+
+ MAR 24
+ UPDATE
+
+
+ Second Halving: 4x Faster ZK Proofs in Two Weeks
+ Another 2x cut to prover time, Poseidon hashing, mining fix, Senoti
+ rate limits, and whitepaper launch.
+ →
+
+
+
+
+ MAR 16
+ UPDATE
+
+
+ Quantum-Safe Signatures, ZK Scaling, and 2x Faster Wormhole Proofs
+ Weekly update on ML-DSA signature scaling, ZK aggregation, wormhole
+ proof speedup, and security reviews.
+ →
+
+
+
+
+ MAR 07
+ PROTOCOL
+
+
+ Wormhole Transactions
+ Weekly update covering wormhole transactions, private block rewards
+ for miners, and consensus bug fixes.
+ →
+
+
+
VIEW ALL POSTS →
+
+
+
+
+
QDAY Podcast
+
+
+
+
+
+
+
+
+
+
+ EP. 18 — Is the Quantum threat really that close?
+
+
1:27:02 · 9 DAYS AGO
+
WATCH ON YOUTUBE →
+
+
+
+
+
+
+
+ EP. 17 — Building A New Sound Money System
+
+
1:12:56 · 1 MONTH AGO
+
WATCH ON YOUTUBE →
+
+
+
VIEW ALL EPISODES →
+
18 episodes on QDay Podcast
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/home/CommunitySection.astro b/website/src/components/features/home/CommunitySection.astro
new file mode 100644
index 0000000..e7ca9f6
--- /dev/null
+++ b/website/src/components/features/home/CommunitySection.astro
@@ -0,0 +1,360 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
diff --git a/website/src/components/features/home/EcosystemSection.astro b/website/src/components/features/home/EcosystemSection.astro
new file mode 100644
index 0000000..6b20774
--- /dev/null
+++ b/website/src/components/features/home/EcosystemSection.astro
@@ -0,0 +1,874 @@
+---
+import { APP_LINKS } from "@/constants/app-links";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+ {t("home.ecosystem.eyebrow")}
+
+
+ {t("home.ecosystem.headline")}
+
+
+
+
+
+
+
+ {t("home.ecosystem.cards.wallet.label")}
+
+
+ {t("home.ecosystem.cards.wallet.description")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {t("home.ecosystem.cards.wallet.beta")}
+
+
+
+
+
+
+
+
+
+ {t("home.ecosystem.cards.technology.label")}
+
+
+ {t("home.ecosystem.cards.technology.description")}
+
+
+
+
+
+
+
+
+
+
+
+ {t("home.ecosystem.cards.technology.nist_badge")}
+
+
+
+
+
+
+
+
+
+ {t("home.ecosystem.cards.network.label")}
+
+
+ {t("home.ecosystem.cards.network.description")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {t("home.ecosystem.cards.network.validators")}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/home/HeroBanner.astro b/website/src/components/features/home/HeroBanner.astro
new file mode 100644
index 0000000..dc67e34
--- /dev/null
+++ b/website/src/components/features/home/HeroBanner.astro
@@ -0,0 +1,360 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+import Button from "@/components/ui/Button.astro";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
{t("home.hero_banner.eyebrow")}
+
+ {t("home.hero_banner.title_line1")} {
+ t("home.hero_banner.title_line2")
+ }
+
+
+
+
+ {t("home.hero_banner.cta_download_wallet")}
+
+
+ {t("home.hero_banner.cta_whitepaper")}
+
+
+
+
+
+ {t("home.hero_banner.freq.wave_mode")}
+ 1,1
+ {t("home.hero_banner.freq.move_cursor")}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/home/NewsletterSection.astro b/website/src/components/features/home/NewsletterSection.astro
new file mode 100644
index 0000000..7cd53b6
--- /dev/null
+++ b/website/src/components/features/home/NewsletterSection.astro
@@ -0,0 +1,376 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+
+ {t("home.newsletter.success.headline")}
+
+
+ {t("home.newsletter.success.sub")}
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/home/ProblemSection.astro b/website/src/components/features/home/ProblemSection.astro
new file mode 100644
index 0000000..6c30993
--- /dev/null
+++ b/website/src/components/features/home/ProblemSection.astro
@@ -0,0 +1,467 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+
+
+
+
+
+ {t("home.problem.eyebrow")}
+
+
+
+
+ {t("home.problem.status_label")}
+
+
+
+
+
+
+
+ {t("home.problem.headline")}
+
+
+
+
+
+
+ {t("home.problem.qubits.label")}
+
+
+ {t("home.problem.qubits.value")}
+
+
+ {t("home.problem.qubits.sub")}
+
+
+
+
+
+
+
+ {t("home.problem.chains.bitcoin.name")}
+
+
+ {t("home.problem.chains.bitcoin.enc")}
+
+
+ {t("home.problem.tags.vulnerable")}
+
+
+
+
+ {t("home.problem.chains.ethereum.name")}
+
+
+ {t("home.problem.chains.ethereum.enc")}
+
+
+ {t("home.problem.tags.vulnerable")}
+
+
+
+
+ {t("home.problem.chains.solana.name")}
+
+
+ {t("home.problem.chains.solana.enc")}
+
+
+ {t("home.problem.tags.vulnerable")}
+
+
+
+
+ {t("home.problem.chains.quantus.name")}
+
+
+ {t("home.problem.chains.quantus.enc_primary")}
+
+
+ {t("home.problem.chains.quantus.enc_secondary")}
+
+
+ {t("home.problem.tags.secure")}
+
+
+ {t("home.problem.chains.quantus.note")}
+
+
+
+
+
+
+
+ {t("home.problem.source")}
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/home/SolutionSection.astro b/website/src/components/features/home/SolutionSection.astro
new file mode 100644
index 0000000..504471c
--- /dev/null
+++ b/website/src/components/features/home/SolutionSection.astro
@@ -0,0 +1,433 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+
+
{t("home.solution.eyebrow")}
+
+ |
+
+
+
+
+
+
+
+
+
+
+ {t("home.solution.pillars.pqc.title")}
+
+
+
+
+ {t("home.solution.pillars.pqc.specs.algorithm.label")}
+
+ {t("home.solution.pillars.pqc.specs.algorithm.value")}
+
+ >
+
+
+
+ {t("home.solution.pillars.pqc.specs.standard.label")}
+
+ {t("home.solution.pillars.pqc.specs.standard.value")}
+
+ >
+
+
+
+ {t("home.solution.pillars.pqc.specs.layer.label")}
+
+ {t("home.solution.pillars.pqc.specs.layer.value")}
+
+ >
+
+
+
+
+
+
+
+
+
+ {t("home.solution.pillars.zk.title")}
+
+
+
+
+ {t("home.solution.pillars.zk.specs.type.label")}
+
+ {t("home.solution.pillars.zk.specs.type.value")}
+
+ >
+
+
+
+ {t("home.solution.pillars.zk.specs.purpose.label")}
+
+ {t("home.solution.pillars.zk.specs.purpose.value")}
+
+ >
+
+
+
+ {t("home.solution.pillars.zk.specs.throughput.label")}
+
+ {t("home.solution.pillars.zk.specs.throughput.value")}
+
+ >
+
+
+
+
+
+
+
+
+
+ {t("home.solution.pillars.arch.title")}
+
+
+
+
+ {t("home.solution.pillars.arch.specs.type.label")}
+
+ {t("home.solution.pillars.arch.specs.type.value")}
+
+ >
+
+
+
+ {t("home.solution.pillars.arch.specs.approach.label")}
+
+ {t("home.solution.pillars.arch.specs.approach.value")}
+
+ >
+
+
+
+ {t("home.solution.pillars.arch.specs.migration.label")}
+
+ {t("home.solution.pillars.arch.specs.migration.value")}
+
+ >
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/home/TerminalLoader.astro b/website/src/components/features/home/TerminalLoader.astro
new file mode 100644
index 0000000..781610d
--- /dev/null
+++ b/website/src/components/features/home/TerminalLoader.astro
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
diff --git a/website/src/components/features/home/app-download/AppDownload.astro b/website/src/components/features/home/app-download/AppDownload.astro
deleted file mode 100644
index b3485a4..0000000
--- a/website/src/components/features/home/app-download/AppDownload.astro
+++ /dev/null
@@ -1,72 +0,0 @@
----
-import CallToAction from "./CallToAction.astro";
-
-import AppHomeView from "@/assets/download/app-home-view.png";
-import { Image } from "astro:assets";
-
-import AppBenefitCard from "@/components/ui/AppBenefitCard.astro";
-import AppInformation from "@/components/ui/AppInformation.astro";
-
-import { BENEFIT_DATA } from "@/constants/app-benefits";
-import SphereDecoration from "@/components/ui/SphereDecoration.astro";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- BENEFIT_DATA.map((data) => (
-
- ))
- }
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/website/src/components/features/home/app-download/CallToAction.astro b/website/src/components/features/home/app-download/CallToAction.astro
deleted file mode 100644
index 1178d29..0000000
--- a/website/src/components/features/home/app-download/CallToAction.astro
+++ /dev/null
@@ -1,47 +0,0 @@
----
-import Button from "@/components/ui/Button.astro";
-import SphereDecoration from "@/components/ui/SphereDecoration.astro";
-import {
- createTranslator,
- getLocaleFromUrl,
- getLocalizedPath,
-} from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
-
-
-
-
- {t("app.cta.tagline")}
-
-
-
-
- {t("app.cta.title")}
-
-
- {t("app.cta.button")}
-
-
-
diff --git a/website/src/components/features/home/benefits/Benefits.astro b/website/src/components/features/home/benefits/Benefits.astro
deleted file mode 100644
index edbf5f7..0000000
--- a/website/src/components/features/home/benefits/Benefits.astro
+++ /dev/null
@@ -1,86 +0,0 @@
----
-import SphereDecoration from "@/components/ui/SphereDecoration.astro";
-import type { Props as CardData } from "./Card.astro";
-import Card from "./Card.astro";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
-
-const cardData: CardData[] = [
- {
- title: "benefits.cards.quantum_secure.title",
- body: "benefits.cards.quantum_secure.description",
- variant: "benefit-1",
- qips: [
- {
- href: "https://github.com/Quantus-Network/improvement-proposals/blob/main/qip-0002.md",
- label: "QIP-002",
- },
- {
- href: "https://github.com/Quantus-Network/improvement-proposals/blob/main/qip-0006.md",
- label: "QIP-006",
- },
- ],
- },
- {
- title: "benefits.cards.zero_knowledge.title",
- body: "benefits.cards.zero_knowledge.description",
- variant: "benefit-2",
- qips: [
- {
- href: "https://github.com/Quantus-Network/improvement-proposals/blob/main/qip-0005.md",
- label: "QIP-005",
- },
- ],
- },
- {
- title: "benefits.cards.security_control.title",
- body: "benefits.cards.security_control.description",
- variant: "benefit-3",
- qips: [
- {
- href: "https://github.com/Quantus-Network/improvement-proposals/blob/main/qip-0011.md",
- label: "QIP-011",
- },
- ],
- },
-];
----
-
-
-
-
- FOUNDATIONS
-
-
- {t("benefits.title")}
-
-
-
- {t("benefits.description")}
-
-
-
-
- {
- cardData.map(({ title, body, ...rest }) => (
-
- ))
- }
-
-
diff --git a/website/src/components/features/home/benefits/Card.astro b/website/src/components/features/home/benefits/Card.astro
deleted file mode 100644
index 0d268ef..0000000
--- a/website/src/components/features/home/benefits/Card.astro
+++ /dev/null
@@ -1,62 +0,0 @@
----
-import Tag from "@/components/ui/Tag.astro";
-import BenefitOne from "@/assets/benefits/benefit-1.svg";
-import BenefitTwo from "@/assets/benefits/benefit-2.svg";
-import BenefitThree from "@/assets/benefits/benefit-3.svg";
-
-type Qip = { label: string; href: string };
-type Variant = "benefit-1" | "benefit-2" | "benefit-3";
-
-export interface Props {
- variant: Variant;
- title: string;
- body: string;
- qips: Qip[];
-}
-
-const { body, qips, title, variant } = Astro.props;
----
-
-
-
- {
- variant === "benefit-1" && (
-
- )
- }
- {
- variant === "benefit-2" && (
-
- )
- }
- {
- variant === "benefit-3" && (
-
- )
- }
-
-
-
-
- {title}
-
-
-
- {body}
-
-
-
-
-
diff --git a/website/src/components/features/home/events/Events.astro b/website/src/components/features/home/events/Events.astro
deleted file mode 100644
index a0499c2..0000000
--- a/website/src/components/features/home/events/Events.astro
+++ /dev/null
@@ -1,74 +0,0 @@
----
-import { Image } from "astro:assets";
-import Button from "@/components/ui/Button.astro";
-
-import Token2049 from "@/assets/events/token-2049-singapore.png";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
- EVENTS
-
- {t("events.title")}
-
-
-
-
-
-
-
-
-
{t("events.upcoming")}
-
- {t("events.token2049.title")}
-
-
- {t("events.token2049.date")}
-
-
-
-
-
- {t("events.token2049.description")}
-
-
-
{t("events.token2049.additional")}
-
-
{t("events.token2049.cta")}
-
-
-
-
-
- {t("events.token2049.cta")}
-
diff --git a/website/src/components/features/home/hero-banner/Banner.astro b/website/src/components/features/home/hero-banner/Banner.astro
deleted file mode 100644
index a0c7f6b..0000000
--- a/website/src/components/features/home/hero-banner/Banner.astro
+++ /dev/null
@@ -1,39 +0,0 @@
----
-import Button from "@/components/ui/Button.astro";
-import {
- createTranslator,
- getLocaleFromUrl,
- getLocalizedPath,
-} from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
-
{t("hero.tagline")}
-
- {t("hero.title")}
-
-
- {t("hero.subtitle")}
-
-
-
-
- {t("hero.cta_primary")}
- {t("hero.cta_secondary")}
-
-
diff --git a/website/src/components/features/home/hero-banner/HeroBanner.astro b/website/src/components/features/home/hero-banner/HeroBanner.astro
deleted file mode 100644
index 7d79b89..0000000
--- a/website/src/components/features/home/hero-banner/HeroBanner.astro
+++ /dev/null
@@ -1,35 +0,0 @@
----
-import Separator from "@/components/ui/Separator.astro";
-import Banner from "./Banner.astro";
-import Stats from "./Stats.astro";
-import SphereDecoration from "@/components/ui/SphereDecoration.astro";
----
-
-
diff --git a/website/src/components/features/home/hero-banner/Stats.astro b/website/src/components/features/home/hero-banner/Stats.astro
deleted file mode 100644
index 42f6dcb..0000000
--- a/website/src/components/features/home/hero-banner/Stats.astro
+++ /dev/null
@@ -1,156 +0,0 @@
----
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
-
- 12{t("hero.stats.seconds")}
-
-
{t("hero.stats.blocktime")}
-
-
-
-
-
-
- -
-
-
{t("hero.stats.transactions")}
-
-
-
-
-
-
- -
-
-
{t("hero.stats.addresses")}
-
-
-
-
-
-
- -
-
-
{t("hero.stats.nodes")}
-
-
-
-
-
-
-
-
-
diff --git a/website/src/components/features/home/introduction-video/IntroductionVideo.astro b/website/src/components/features/home/introduction-video/IntroductionVideo.astro
deleted file mode 100644
index a04a5a0..0000000
--- a/website/src/components/features/home/introduction-video/IntroductionVideo.astro
+++ /dev/null
@@ -1,135 +0,0 @@
----
-import SiteSocials from "@/components/ui/SiteSocials.astro";
-import { PlayIcon } from "@lucide/astro";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-import { Image } from "astro:assets";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
-
-const VIDEO_ID = "ZoT5cdMoMPA";
-const THUMBNAIL_URL = `https://i.ytimg.com/vi/${VIDEO_ID}/sddefault.jpg`;
----
-
-
-
-
-
-
- {t("video.title")}
-
-
- {t("video.description")}
-
-
-
-
-
-
diff --git a/website/src/components/features/home/roadmap/Roadmap.astro b/website/src/components/features/home/roadmap/Roadmap.astro
deleted file mode 100644
index 23ef9cd..0000000
--- a/website/src/components/features/home/roadmap/Roadmap.astro
+++ /dev/null
@@ -1,70 +0,0 @@
----
-import SphereDecoration from "@/components/ui/SphereDecoration.astro";
-import Timeline from "./Timeline.astro";
-import type { Props as TimelineData } from "./TimelineItem.astro";
-import TimelineItem from "./TimelineItem.astro";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
-
-const timelineData: TimelineData[] = [
- {
- date: t("roadmap.timeline.heisenberg.date"),
- title: t("roadmap.timeline.heisenberg.title"),
- content: t("roadmap.timeline.heisenberg.content"),
- },
- {
- date: t("roadmap.timeline.resonance.date"),
- title: t("roadmap.timeline.resonance.title"),
- content: t("roadmap.timeline.resonance.content"),
- },
- {
- date: t("roadmap.timeline.schrodinger.date"),
- title: t("roadmap.timeline.schrodinger.title"),
- content: t("roadmap.timeline.schrodinger.content"),
- },
- {
- date: t("roadmap.timeline.bell.date"),
- title: t("roadmap.timeline.bell.title"),
- content: t("roadmap.timeline.bell.content"),
- },
- {
- date: t("roadmap.timeline.planck.date"),
- title: t("roadmap.timeline.planck.title"),
- content: t("roadmap.timeline.planck.content"),
- },
- {
- date: t("roadmap.timeline.dirac.date"),
- title: t("roadmap.timeline.dirac.title"),
- content: t("roadmap.timeline.dirac.content"),
- },
-];
----
-
-
-
-
-
-
-
- {t("roadmap.title")}
-
-
-
- {timelineData.map((data) => )}
-
-
diff --git a/website/src/components/features/home/roadmap/Timeline.astro b/website/src/components/features/home/roadmap/Timeline.astro
deleted file mode 100644
index 198c83f..0000000
--- a/website/src/components/features/home/roadmap/Timeline.astro
+++ /dev/null
@@ -1,20 +0,0 @@
----
-import { applyStyles } from "@/utils/apply-styles";
-
-const { class: className } = Astro.props;
----
-
-
-
-
diff --git a/website/src/components/features/home/roadmap/TimelineItem.astro b/website/src/components/features/home/roadmap/TimelineItem.astro
deleted file mode 100644
index caa7cef..0000000
--- a/website/src/components/features/home/roadmap/TimelineItem.astro
+++ /dev/null
@@ -1,32 +0,0 @@
----
-export interface Props {
- date: string;
- title: string;
- content: string;
-}
-
-const { date, title, content } = Astro.props;
----
-
-
-
-
-
-
{date}
-
{title}
-
{content}
-
-
-
-
diff --git a/website/src/components/features/home/teams/ExtraCard.astro b/website/src/components/features/home/teams/ExtraCard.astro
deleted file mode 100644
index e5435bb..0000000
--- a/website/src/components/features/home/teams/ExtraCard.astro
+++ /dev/null
@@ -1,44 +0,0 @@
----
-import SocialX from "@/assets/socials/social-x.svg";
-import SocialGithub from "@/assets/socials/social-github.svg";
-import { Globe } from "@lucide/astro";
-import Separator from "@/components/ui/Separator.astro";
-
-export interface Props {
- name: string;
- title: string;
- subTitles: string[];
- social: {
- href: string;
- type: "x" | "website" | "github";
- };
-}
-
-const { name, title, subTitles, social } = Astro.props;
----
-
-
diff --git a/website/src/components/features/home/teams/ProfileCard.astro b/website/src/components/features/home/teams/ProfileCard.astro
deleted file mode 100644
index 65cd831..0000000
--- a/website/src/components/features/home/teams/ProfileCard.astro
+++ /dev/null
@@ -1,35 +0,0 @@
----
-import { Image } from "astro:assets";
-import type { ImageMetadata } from "astro";
-import Separator from "@/components/ui/Separator.astro";
-
-export interface Props {
- name: string;
- title: string;
- avatar: {
- alt: string;
- src: ImageMetadata;
- };
-}
-
-const { name, title, avatar } = Astro.props;
----
-
-
-
-
-
-
-
- {name}
-
-
-
- {title}
-
-
diff --git a/website/src/components/features/home/teams/Teams.astro b/website/src/components/features/home/teams/Teams.astro
deleted file mode 100644
index 60ef41a..0000000
--- a/website/src/components/features/home/teams/Teams.astro
+++ /dev/null
@@ -1,193 +0,0 @@
----
-import { Image } from "astro:assets";
-
-import type { Props as ProfileData } from "./ProfileCard.astro";
-import type { Props as ExtraData } from "./ExtraCard.astro";
-import Button from "@/components/ui/Button.astro";
-import Separator from "@/components/ui/Separator.astro";
-import SocialX from "@/assets/socials/social-x.svg";
-import SocialGithub from "@/assets/socials/social-github.svg";
-import { Globe } from "@lucide/astro";
-
-import Chris from "@/assets/teams/chris-avatar.png";
-import Joe from "@/assets/teams/joe-avatar.png";
-import Nik from "@/assets/teams/nik-avatar.png";
-import Cezary from "@/assets/teams/cezary-avatar.png";
-import ProfileCard from "./ProfileCard.astro";
-import {
- createTranslator,
- getLocaleFromUrl,
- getLocalizedPath,
-} from "@/utils/i18n";
-import ExtraCard from "./ExtraCard.astro";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
-
-const profileData: (ProfileData & {
- social: { href: string; type: string };
-})[] = [
- {
- name: "Joe Mattia",
- title: "Chief Operating Officer",
- avatar: {
- alt: "Joe Mattia's avatar",
- src: Joe,
- },
- social: { href: "https://x.com/joemattia", type: "x" },
- },
- {
- name: "Nikolaus Heger",
- title: "Senior Software Engineer",
- avatar: {
- alt: "Nikolaus Heger's avatar",
- src: Nik,
- },
- social: {
- href: "https://github.com/n13",
- type: "github",
- },
- },
- {
- name: "Cezary Olborski",
- title: "Senior Software Engineer",
- avatar: {
- alt: "Cezary Olborski's avatar",
- src: Cezary,
- },
- social: {
- href: "https://github.com/czareko",
- type: "github",
- },
- },
-];
-
-const extraProfiles: ExtraData[] = [
- {
- name: "Balaji Srinivasan",
- title: "Key Investor",
- subTitles: [
- "Author of The Network State.",
- "Founder of The Network School.",
- ],
- social: {
- href: "https://x.com/balajis",
- type: "x",
- },
- },
- {
- name: "Raghav Gulati",
- title: "Strategic Advisor",
- subTitles: ["CEO Coinlist"],
- social: {
- href: "https://x.com/rargulati",
- type: "x",
- },
- },
-];
----
-
-
-
-
-
-
-
-
{t("team.title")}
-
-
{t("team.description")}
-
-
-
{t("team.cta")}
-
-
-
-
-
-
-
-
-
-
- Christopher Smith
-
-
- Chief Executive Officer
-
-
-
-
-
- {t("team.members.chris.bio")}
-
-
-
-
-
- {t("team.members.chris.achievements.0")}
- {t("team.members.chris.achievements.1")}
- {t("team.members.chris.achievements.2")}
- {t("team.members.chris.achievements.3")}
- {t("team.members.chris.achievements.4")}
-
-
-
-
-
-
-
-
-
-
- {extraProfiles.map((data) => )}
-
-
-
diff --git a/website/src/components/features/launch/AllocationChart.astro b/website/src/components/features/launch/AllocationChart.astro
deleted file mode 100644
index 22020b2..0000000
--- a/website/src/components/features/launch/AllocationChart.astro
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
diff --git a/website/src/components/features/launch/ResponsiveLaunchCardsTable.astro b/website/src/components/features/launch/ResponsiveLaunchCardsTable.astro
deleted file mode 100644
index fc241d8..0000000
--- a/website/src/components/features/launch/ResponsiveLaunchCardsTable.astro
+++ /dev/null
@@ -1,93 +0,0 @@
----
-interface Props {
- headers: string[];
- rows: string[][];
- labelColumn?: number;
- class?: string;
-
- // Allows the caller to preserve per-table desktop row styling (e.g. "Total" bold + top border).
- desktopRowClassName?: string;
- desktopLastRowClassName?: string;
-
- // Allows the caller to preserve per-table emphasis in the mobile card layout.
- mobileLastRowClassName?: string;
-}
-
-const {
- headers,
- rows,
- labelColumn = 0,
- class: className,
- desktopRowClassName = "border-quantus-white/10 border-b",
- desktopLastRowClassName,
- mobileLastRowClassName,
-} = Astro.props;
-
-const safeLabelColumn = Math.max(0, Math.min(labelColumn, headers.length - 1));
-const cellValue = (row: string[], colIndex: number) => row[colIndex] ?? "";
----
-
-
- {/* Desktop/tablet: standard table */}
-
-
-
-
- {headers.map((header) => (
- {header}
- ))}
-
-
-
- {rows.map((row, rowIndex) => {
- const isLast = rowIndex === rows.length - 1;
- const trClass =
- isLast && desktopLastRowClassName ? desktopLastRowClassName : desktopRowClassName;
-
- return (
-
- {headers.map((_, colIndex) => (
- {cellValue(row, colIndex)}
- ))}
-
- );
- })}
-
-
-
-
- {/* Mobile: stacked cards (shows all columns as label/value pairs) */}
-
- {rows.map((row, rowIndex) => {
- const isLast = rowIndex === rows.length - 1;
-
- return (
-
-
- {cellValue(row, safeLabelColumn)}
-
-
-
- {headers.map((header, colIndex) => {
- if (colIndex === safeLabelColumn) return null;
- return (
-
- {header}
-
- {cellValue(row, colIndex)}
-
-
- );
- })}
-
-
- );
- })}
-
-
-
diff --git a/website/src/components/features/launch/VestingLockups.astro b/website/src/components/features/launch/VestingLockups.astro
deleted file mode 100644
index 187643d..0000000
--- a/website/src/components/features/launch/VestingLockups.astro
+++ /dev/null
@@ -1,154 +0,0 @@
----
-interface Props {
- t: (key: string) => string;
-}
-
-const { t } = Astro.props;
----
-
-
-
-
-
- {t("launch.vesting.mark_tge")}
- {t("launch.vesting.mark_y1")}
- {t("launch.vesting.mark_y2")}
- {t("launch.vesting.mark_y3")}
- {t("launch.vesting.mark_y4")}
-
-
-
-
-
-
- {t("launch.vesting.mark_tge")}
- {t("launch.vesting.mark_y1")}
- {t("launch.vesting.mark_y2")}
- {t("launch.vesting.mark_y3")}
- {t("launch.vesting.mark_y4")}
-
-
-
-
-
-
- {t("launch.vesting.row_investors")}
-
-
-
- {t("launch.vesting.investors_bar")}
-
-
-
-
-
-
-
- {t("launch.vesting.row_dex")}
-
-
-
- {t("launch.vesting.dex_bar")}
-
-
-
-
-
-
-
- {t("launch.vesting.row_team")}
-
-
-
- {t("launch.vesting.cliff")}
-
-
- {t("launch.vesting.linear_monthly")}
-
-
-
-
-
-
-
- {t("launch.vesting.row_advisors")}
-
-
-
- {t("launch.vesting.cliff")}
-
-
- {t("launch.vesting.linear_monthly")}
-
-
-
-
-
-
-
- {t("launch.vesting.row_company")}
-
-
-
- {t("launch.vesting.company_bar")}
-
-
-
-
diff --git a/website/src/components/features/qday-checker/AdviceSection.astro b/website/src/components/features/qday-checker/AdviceSection.astro
new file mode 100644
index 0000000..0f45f80
--- /dev/null
+++ b/website/src/components/features/qday-checker/AdviceSection.astro
@@ -0,0 +1,74 @@
+
+
+
+
WHAT TO DO NEXT
+
+ Got risk? Here's what to do about it.
+
+
+ If your wallet is exposed, the only real solution is moving your assets to
+ a quantum-secure address. The Quantus wallet is built on a chain where
+ every transaction is signed with post-quantum cryptography, meaning your
+ assets are protected not just today, but when quantum computers arrive.
+
+
DOWNLOAD THE QUANTUS WALLET →
+
+
+
+
+
diff --git a/website/src/components/features/qday-checker/DefinitionSection.astro b/website/src/components/features/qday-checker/DefinitionSection.astro
new file mode 100644
index 0000000..226c2f9
--- /dev/null
+++ b/website/src/components/features/qday-checker/DefinitionSection.astro
@@ -0,0 +1,45 @@
+
+
+
+
THE QUANTUM DEADLINE
+
+ Q-Day is coming.
+
+
+ Q-Day is the moment quantum computers become powerful enough to break the
+ cryptography securing most of today's digital assets. Once your public key
+ is exposed, a sufficiently powerful quantum computer can derive your
+ private key and drain your wallet without your knowledge.
+
+
+ The window to act is open. It will not stay that way.
+
+
+
+
+
diff --git a/website/src/components/features/qday-checker/HeroBanner.astro b/website/src/components/features/qday-checker/HeroBanner.astro
new file mode 100644
index 0000000..4e56dc8
--- /dev/null
+++ b/website/src/components/features/qday-checker/HeroBanner.astro
@@ -0,0 +1,714 @@
+
+
+
QUANTUM RISK CHECKER
+
Is your wallet exposed?
+
+ Enter any Ethereum address. We will scan its transaction history and
+ balance to calculate your quantum vulnerability. Know your risk before
+ Q-Day arrives.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/qday-checker/MethodSection.astro b/website/src/components/features/qday-checker/MethodSection.astro
new file mode 100644
index 0000000..26527e9
--- /dev/null
+++ b/website/src/components/features/qday-checker/MethodSection.astro
@@ -0,0 +1,107 @@
+
+
+
+
HOW IT WORKS
+
+ Two risk factors. One score.
+
+
+ The Quantum Risk Checker scans any Ethereum address or ENS name and
+ calculates a Quantum Readiness Score based on two signals:
+
+
+
+
+
PUBLIC KEY EXPOSURE
+
+ Every outgoing transaction permanently exposes your public key
+ on-chain. The longer it has been exposed, the higher the risk.
+
+
+
+
BALANCE SENSITIVITY
+
+ The higher the balance in an exposed wallet, the more attractive the
+ target. High balance combined with an exposed key means maximum risk.
+
+
+
+
+
+
+
diff --git a/website/src/components/features/quests/body-layout/BodyLayout.astro b/website/src/components/features/quests/body-layout/BodyLayout.astro
deleted file mode 100644
index 9ced12f..0000000
--- a/website/src/components/features/quests/body-layout/BodyLayout.astro
+++ /dev/null
@@ -1,15 +0,0 @@
----
-import Decoration from "./Decoration.astro";
----
-
-
diff --git a/website/src/components/features/quests/body-layout/Decoration.astro b/website/src/components/features/quests/body-layout/Decoration.astro
deleted file mode 100644
index 3862dc5..0000000
--- a/website/src/components/features/quests/body-layout/Decoration.astro
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/website/src/components/features/quests/hero-banner/HeroBanner.astro b/website/src/components/features/quests/hero-banner/HeroBanner.astro
deleted file mode 100644
index cf2daf4..0000000
--- a/website/src/components/features/quests/hero-banner/HeroBanner.astro
+++ /dev/null
@@ -1,29 +0,0 @@
----
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-import { Image } from "astro:assets";
-import QQLogo from "@/assets/quests/qq-logo.png";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
-
{t("quests.hero.welcome")}
-
-
{t("quests.hero.title")}
-
-
-
- {t("quests.hero.description")}
-
-
-
diff --git a/website/src/components/features/quests/raid/information/Information.astro b/website/src/components/features/quests/raid/information/Information.astro
deleted file mode 100644
index f6f36d8..0000000
--- a/website/src/components/features/quests/raid/information/Information.astro
+++ /dev/null
@@ -1,95 +0,0 @@
----
-import { APP_LINKS } from "@/constants/app-links";
-import AppleStore from "@/assets/download/apple-store-download.png";
-import GooglePlay from "@/assets/download/google-play-download.png";
-import KingOfTheShill from "@/assets/quests/king-of-the-shill.png";
-import { Image } from "astro:assets";
-import Decoration from "../../body-layout/Decoration.astro";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
diff --git a/website/src/components/features/quests/raid/leaderboard/Leaderboard.astro b/website/src/components/features/quests/raid/leaderboard/Leaderboard.astro
deleted file mode 100644
index cdc950c..0000000
--- a/website/src/components/features/quests/raid/leaderboard/Leaderboard.astro
+++ /dev/null
@@ -1,15 +0,0 @@
----
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-import LeaderboardPodium from "./leaderboard-podium/LeaderboardPodium";
-import LeaderboardTable from "./leaderboard-table/LeaderboardTable";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
- {t("quests.raid.leaderboard.title")}
-
-
-
-
diff --git a/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/Hook.tsx b/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/Hook.tsx
deleted file mode 100644
index 0f1efe0..0000000
--- a/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/Hook.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { useCallback, useEffect, useState } from "react";
-
-import api, { type RaidLeaderboardResponse } from "@/api/client";
-
-import useFetch from "@/hooks/useFetch";
-import { DATA_POOL_INTERVAL } from "@/constants/data-pool-interval";
-import { createTranslator, type Locale } from "@/utils/i18n";
-import { QUERY_DEFAULT_LIMIT } from "@/constants/query-default-limit";
-
-export const useWinnerPodium = (locale: Locale) => {
- const [t, setT] = useState
(null);
-
- const fetchFn = useCallback(async () => {
- const res = await api.fetchRaidLeaderboard({
- page: 1,
- pageSize: QUERY_DEFAULT_LIMIT,
- });
- return res.json();
- }, []);
-
- const {
- data,
- loading: fetchLoading,
- error: fetchError,
- } = useFetch({
- fetchFn,
- polling: {
- enabled: true,
- interval: DATA_POOL_INTERVAL,
- },
- });
-
- const loading = fetchLoading || t === null;
- const success = t !== null && !loading && !fetchError;
- const error = !loading && fetchError;
-
- const getStatus = (): "success" | "error" | "loading" | "idle" => {
- switch (true) {
- case success:
- return "success";
- case !!error:
- return "error";
- case !!loading:
- return "loading";
- default:
- return "idle";
- }
- };
-
- useEffect(() => {
- const loadTranslation = async () => {
- const tFn = await createTranslator(locale);
- setT(() => tFn); // ← Use function updater to set a function
- };
-
- loadTranslation();
- }, [locale]);
-
- return {
- data,
- status: getStatus(),
- error,
- t,
- };
-};
diff --git a/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/LeaderboardPodium.tsx b/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/LeaderboardPodium.tsx
deleted file mode 100644
index 7d1a699..0000000
--- a/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/LeaderboardPodium.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import type { Locale } from "@/utils/i18n";
-import { useWinnerPodium } from "./Hook";
-import WinnerPodium from "./WinnerPodium";
-
-interface LeaderboardPodiumProps {
- locale: Locale;
-}
-
-const LeaderboardPodium = ({ locale }: LeaderboardPodiumProps) => {
- const { data, error, status, t } = useWinnerPodium(locale);
-
- const firstRank = data?.data[0];
- const secondRank = data?.data[1];
- const thirdRank = data?.data[2];
-
- const isLoading = status === "loading";
-
- return (
-
- {error &&
{error.message}
}
-
-
-
-
-
-
-
- );
-};
-
-export default LeaderboardPodium;
diff --git a/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/WinnerPodium.tsx b/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/WinnerPodium.tsx
deleted file mode 100644
index e75d049..0000000
--- a/website/src/components/features/quests/raid/leaderboard/leaderboard-podium/WinnerPodium.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import { Skeleton } from "@/components/ui/react/Skeleton";
-import { applyStyles } from "@/utils/apply-styles";
-import type { TranslationKey, TranslationParams } from "@/utils/i18n";
-
-interface WinnerPodiumProps {
- rank: 1 | 2 | 3;
- identity?: string;
- impressions?: number;
- isLoading: boolean;
- t: (key: TranslationKey, params?: TranslationParams) => any;
-}
-
-const prizeMap = {
- 1: 300,
- 2: 150,
- 3: 50,
-};
-
-const WinnerPodium = ({
- identity,
- rank,
- impressions,
- isLoading,
- t,
-}: WinnerPodiumProps) => {
- return (
-
-
- {rank == 1 && (
-
- )}
- {rank == 2 && (
-
- )}
- {rank == 3 && (
-
- )}
-
-
- {isLoading ? (
-
- ) : (
-
- {identity ?? "-"}
-
- )}
-
-
-
-
-
-
-
- {isLoading ? (
-
- ) : (
- `${impressions ?? "-"} ${t("quests.raid.leaderboard.impressions")}`
- )}
-
-
-
-
-
-
-
- ${prizeMap[rank]}
- USDC
-
-
-
-
-
- );
-};
-
-export default WinnerPodium;
diff --git a/website/src/components/features/quests/raid/leaderboard/leaderboard-table/Columns.tsx b/website/src/components/features/quests/raid/leaderboard/leaderboard-table/Columns.tsx
deleted file mode 100644
index a7f21f2..0000000
--- a/website/src/components/features/quests/raid/leaderboard/leaderboard-table/Columns.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { RaidLeaderboardEntrant } from "@/api/client";
-import { createColumnHelper } from "@tanstack/react-table";
-
-const columnHelper = createColumnHelper();
-
-export const LEADERBOARD_COLUMNS = [
- columnHelper.accessor("rank", {
- id: "rank",
- header: "quests.raid.leaderboard.table.rank",
- cell: (props) => (
-
- {props.getValue()}
-
- ),
- enableSorting: false,
- }),
- columnHelper.accessor("raider.referral_code", {
- id: "address",
- header: "quests.raid.leaderboard.table.address",
- cell: (props) => props.getValue(),
- enableSorting: false,
- }),
- columnHelper.accessor("total_impressions", {
- id: "impressions",
- header: "quests.raid.leaderboard.table.impressions",
- cell: (props) => (
-
- {props.getValue()}
-
- ),
- enableSorting: false,
- }),
-];
diff --git a/website/src/components/features/quests/raid/leaderboard/leaderboard-table/Hook.tsx b/website/src/components/features/quests/raid/leaderboard/leaderboard-table/Hook.tsx
deleted file mode 100644
index 552509d..0000000
--- a/website/src/components/features/quests/raid/leaderboard/leaderboard-table/Hook.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-import type { OnChangeFn, PaginationState } from "@tanstack/react-table";
-import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
-import { useCallback, useEffect, useMemo, useState } from "react";
-
-import api, {
- type RaidLeaderboardEntrant,
- type RaidLeaderboardResponse,
-} from "@/api/client";
-import { LEADERBOARD_COLUMNS } from "./Columns";
-import { QUERY_DEFAULT_LIMIT } from "@/constants/query-default-limit";
-import useFetch from "@/hooks/useFetch";
-import { DATA_POOL_INTERVAL } from "@/constants/data-pool-interval";
-import { createTranslator, type Locale } from "@/utils/i18n";
-import { useDebounceCallback } from "usehooks-ts";
-import { INPUT_DEBOUNCE_INTERVAL } from "@/constants/debounce-interval";
-
-export const useLeaderboardTable = (locale: Locale) => {
- const [t, setT] = useState(null);
- const [page, setPage] = useState(1);
- const [keyword, setKeyword] = useState("");
-
- const pageSize = QUERY_DEFAULT_LIMIT;
- const currentPageIndex = page - 1;
- const paginationValue: PaginationState = {
- pageSize,
- pageIndex: currentPageIndex,
- };
-
- const updateKeywordFn = useCallback(
- (newKeyword: string) => {
- setKeyword(newKeyword.trim());
- setPage(1);
- },
- [setKeyword],
- );
-
- const handleChangeKeyword = useDebounceCallback(
- updateKeywordFn,
- INPUT_DEBOUNCE_INTERVAL,
- );
-
- const handleChangePagination: OnChangeFn = (pagination) => {
- if (typeof pagination === "function") {
- const newPagination = pagination(paginationValue);
-
- setPage(newPagination.pageIndex + 1);
- } else {
- setPage(pagination.pageIndex + 1);
- }
- };
-
- const normalizeData = (fetchData: RaidLeaderboardResponse | null) =>
- (fetchData?.data ?? []).filter((data) => ![1, 2, 3].includes(data.rank));
-
- const fetchFn = useCallback(async () => {
- const res = await api.fetchRaidLeaderboard({
- page,
- pageSize,
- filterByReferralCode: keyword,
- });
- return res.json();
- }, [page, pageSize, keyword]);
-
- const {
- data: fetchData,
- loading: fetchLoading,
- error: fetchError,
- } = useFetch({
- fetchFn,
- polling: {
- enabled: true,
- interval: DATA_POOL_INTERVAL,
- },
- });
-
- const columns = useMemo(() => LEADERBOARD_COLUMNS, []);
- const [rowCount, setRowCount] = useState(
- fetchData?.meta.total_items ?? 0,
- );
-
- const data = normalizeData(fetchData);
-
- const table = useReactTable({
- data,
- columns,
- getCoreRowModel: getCoreRowModel(),
- state: {
- pagination: paginationValue,
- },
- rowCount,
- onPaginationChange: handleChangePagination,
- manualPagination: true,
- });
-
- const loading = fetchLoading || t === null;
- const success = t !== null && !loading && !fetchError;
- const error = !loading && fetchError;
-
- const getStatus = () => {
- switch (true) {
- case success:
- return "success";
- case !!error:
- return "error";
- case !!loading:
- return "loading";
- default:
- return "idle";
- }
- };
-
- useEffect(() => {
- if (!loading && fetchData?.meta.total_items)
- setRowCount(fetchData.meta.total_items);
- }, [loading, fetchData?.meta.total_items]);
-
- useEffect(() => {
- const loadTranslation = async () => {
- const tFn = await createTranslator(locale);
- setT(() => tFn); // ← Use function updater to set a function
- };
-
- loadTranslation();
- }, [locale]);
-
- return {
- handleChangeKeyword,
- table,
- getStatus,
- error,
- t,
- };
-};
diff --git a/website/src/components/features/quests/raid/leaderboard/leaderboard-table/LeaderboardTable.tsx b/website/src/components/features/quests/raid/leaderboard/leaderboard-table/LeaderboardTable.tsx
deleted file mode 100644
index f839ef0..0000000
--- a/website/src/components/features/quests/raid/leaderboard/leaderboard-table/LeaderboardTable.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { DataTable } from "@/components/ui/react/composite/data-table/DataTable";
-
-import { useLeaderboardTable } from "./Hook";
-import type { Locale } from "@/utils/i18n";
-import { Input } from "@/components/ui/react/Input";
-
-interface LeaderboardTableProps {
- locale: Locale;
-}
-
-const LeaderboardTable = ({ locale }: LeaderboardTableProps) => {
- const { handleChangeKeyword, getStatus, table, error, t } =
- useLeaderboardTable(locale);
-
- return (
- <>
-
- Search your entry
-
- {
- const newKeyword = e.target.value;
-
- handleChangeKeyword(newKeyword);
- }}
- />
-
-
- Error: {error && error.message}
- ),
- }}
- withControls
- t={t}
- />
- >
- );
-};
-
-export default LeaderboardTable;
diff --git a/website/src/components/features/quests/raid/rules/Card.astro b/website/src/components/features/quests/raid/rules/Card.astro
deleted file mode 100644
index f3bc926..0000000
--- a/website/src/components/features/quests/raid/rules/Card.astro
+++ /dev/null
@@ -1,21 +0,0 @@
----
-import Separator from "@/components/ui/Separator.astro";
-import { applyStyles } from "@/utils/apply-styles";
-
-export interface Props {
- class?: string;
-}
-
-const { class: className } = Astro.props;
----
-
-
-
-
-
-
diff --git a/website/src/components/features/quests/raid/rules/Rules.astro b/website/src/components/features/quests/raid/rules/Rules.astro
deleted file mode 100644
index 551d72c..0000000
--- a/website/src/components/features/quests/raid/rules/Rules.astro
+++ /dev/null
@@ -1,62 +0,0 @@
----
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-import Card from "./Card.astro";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
- {t("quests.raid.rules.title")}
-
-
-
-
-
-
- {t("quests.raid.rules.goal.title")}
-
-
- {t("quests.raid.rules.goal.content")}
-
-
-
-
-
- {t("quests.raid.rules.prize.title")}
-
-
- {
- t("quests.raid.rules.prize.content").map((val: string) => (
- {val}
- ))
- }
-
-
-
-
-
{t("quests.raid.rules.win.title")}
-
- {t("quests.raid.rules.win.content")}
-
-
-
-
-
-
- {t("quests.raid.rules.win.card.title")}
-
-
-
-
- {t("quests.raid.rules.win.card.content_one")}
-
-
-
- {t("quests.raid.rules.win.card.content_two")}
-
-
-
-
-
diff --git a/website/src/components/features/quests/shill/information/Information.astro b/website/src/components/features/quests/shill/information/Information.astro
deleted file mode 100644
index 137289d..0000000
--- a/website/src/components/features/quests/shill/information/Information.astro
+++ /dev/null
@@ -1,95 +0,0 @@
----
-import { APP_LINKS } from "@/constants/app-links";
-import AppleStore from "@/assets/download/apple-store-download.png";
-import GooglePlay from "@/assets/download/google-play-download.png";
-import KingOfTheShill from "@/assets/quests/king-of-the-shill.png";
-import { Image } from "astro:assets";
-import Decoration from "../../body-layout/Decoration.astro";
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
diff --git a/website/src/components/features/quests/shill/leaderboard/Leaderboard.astro b/website/src/components/features/quests/shill/leaderboard/Leaderboard.astro
deleted file mode 100644
index 2ef760f..0000000
--- a/website/src/components/features/quests/shill/leaderboard/Leaderboard.astro
+++ /dev/null
@@ -1,15 +0,0 @@
----
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-import LeaderboardPodium from "./leaderboard-podium/LeaderboardPodium";
-import LeaderboardTable from "./leaderboard-table/LeaderboardTable";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
- {t("quests.shill.leaderboard.title")}
-
-
-
-
diff --git a/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/Hook.tsx b/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/Hook.tsx
deleted file mode 100644
index af49054..0000000
--- a/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/Hook.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { useCallback, useEffect, useState } from "react";
-
-import api, { type LeaderboardResponse } from "@/api/client";
-
-import useFetch from "@/hooks/useFetch";
-import { DATA_POOL_INTERVAL } from "@/constants/data-pool-interval";
-import { createTranslator, type Locale } from "@/utils/i18n";
-import { QUERY_DEFAULT_LIMIT } from "@/constants/query-default-limit";
-
-export const useWinnerPodium = (locale: Locale) => {
- const [t, setT] = useState(null);
-
- const fetchFn = useCallback(async () => {
- const res = await api.fetchLeaderboard({
- page: 1,
- pageSize: QUERY_DEFAULT_LIMIT,
- });
- return res.json();
- }, []);
-
- const {
- data,
- loading: fetchLoading,
- error: fetchError,
- } = useFetch({
- fetchFn,
- polling: {
- enabled: true,
- interval: DATA_POOL_INTERVAL,
- },
- });
-
- const loading = fetchLoading || t === null;
- const success = t !== null && !loading && !fetchError;
- const error = !loading && fetchError;
-
- const getStatus = (): "success" | "error" | "loading" | "idle" => {
- switch (true) {
- case success:
- return "success";
- case !!error:
- return "error";
- case !!loading:
- return "loading";
- default:
- return "idle";
- }
- };
-
- useEffect(() => {
- const loadTranslation = async () => {
- const tFn = await createTranslator(locale);
- setT(() => tFn); // ← Use function updater to set a function
- };
-
- loadTranslation();
- }, [locale]);
-
- return {
- data,
- status: getStatus(),
- error,
- t,
- };
-};
diff --git a/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/LeaderboardPodium.tsx b/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/LeaderboardPodium.tsx
deleted file mode 100644
index 5fac78f..0000000
--- a/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/LeaderboardPodium.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import type { Locale } from "@/utils/i18n";
-import { useWinnerPodium } from "./Hook";
-import WinnerPodium from "./WinnerPodium";
-
-interface LeaderboardPodiumProps {
- locale: Locale;
-}
-
-const LeaderboardPodium = ({ locale }: LeaderboardPodiumProps) => {
- const { data, error, status, t } = useWinnerPodium(locale);
-
- const firstRank = data?.data[0];
- const secondRank = data?.data[1];
- const thirdRank = data?.data[2];
-
- return (
-
- {error &&
{error.message}
}
-
-
-
-
-
-
-
- );
-};
-
-export default LeaderboardPodium;
diff --git a/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/WinnerPodium.tsx b/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/WinnerPodium.tsx
deleted file mode 100644
index aa1c59b..0000000
--- a/website/src/components/features/quests/shill/leaderboard/leaderboard-podium/WinnerPodium.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-import { Skeleton } from "@/components/ui/react/Skeleton";
-import { applyStyles } from "@/utils/apply-styles";
-import type { TranslationKey, TranslationParams } from "@/utils/i18n";
-
-interface WinnerPodiumProps {
- rank: 1 | 2 | 3;
- identity: string;
- referralCount: number;
- isLoading: boolean;
- t: (key: TranslationKey, params?: TranslationParams) => any;
-}
-
-const prizeMap = {
- 1: 300,
- 2: 150,
- 3: 50,
-};
-
-const WinnerPodium = ({
- identity,
- rank,
- referralCount,
- isLoading,
- t,
-}: WinnerPodiumProps) => {
- return (
-
-
- {rank == 1 && (
-
- )}
- {rank == 2 && (
-
- )}
- {rank == 3 && (
-
- )}
-
-
- {isLoading ? (
-
- ) : (
-
{identity}
- )}
-
-
-
-
-
-
-
- {isLoading ? (
-
- ) : (
- `${referralCount} ${t("quests.shill.leaderboard.referrals")}`
- )}
-
-
-
-
-
-
-
- ${prizeMap[rank]}
- USDC
-
-
-
-
-
- );
-};
-
-export default WinnerPodium;
diff --git a/website/src/components/features/quests/shill/leaderboard/leaderboard-table/Columns.tsx b/website/src/components/features/quests/shill/leaderboard/leaderboard-table/Columns.tsx
deleted file mode 100644
index b9c829f..0000000
--- a/website/src/components/features/quests/shill/leaderboard/leaderboard-table/Columns.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { LeaderboardEntrant } from "@/api/client";
-import { createColumnHelper } from "@tanstack/react-table";
-
-const columnHelper = createColumnHelper();
-
-export const LEADERBOARD_COLUMNS = [
- columnHelper.accessor("rank", {
- id: "rank",
- header: "quests.shill.leaderboard.table.rank",
- cell: (props) => (
-
- {props.getValue()}
-
- ),
- enableSorting: false,
- }),
- columnHelper.accessor("address.referral_code", {
- id: "address",
- header: "quests.shill.leaderboard.table.address",
- cell: (props) => props.getValue(),
- enableSorting: false,
- }),
- columnHelper.accessor("address.referrals_count", {
- id: "referrals_count",
- header: "quests.shill.leaderboard.table.referrals",
- cell: (props) => (
-
- {props.getValue()}
-
- ),
- enableSorting: false,
- }),
-];
diff --git a/website/src/components/features/quests/shill/leaderboard/leaderboard-table/Hook.tsx b/website/src/components/features/quests/shill/leaderboard/leaderboard-table/Hook.tsx
deleted file mode 100644
index 87bcda2..0000000
--- a/website/src/components/features/quests/shill/leaderboard/leaderboard-table/Hook.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-import type { OnChangeFn, PaginationState } from "@tanstack/react-table";
-import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
-import { useCallback, useEffect, useMemo, useState } from "react";
-
-import api, {
- type LeaderboardEntrant,
- type LeaderboardResponse,
-} from "@/api/client";
-import { LEADERBOARD_COLUMNS } from "./Columns";
-import { QUERY_DEFAULT_LIMIT } from "@/constants/query-default-limit";
-import useFetch from "@/hooks/useFetch";
-import { DATA_POOL_INTERVAL } from "@/constants/data-pool-interval";
-import { createTranslator, type Locale } from "@/utils/i18n";
-import { useDebounceCallback } from "usehooks-ts";
-import { INPUT_DEBOUNCE_INTERVAL } from "@/constants/debounce-interval";
-
-export const useLeaderboardTable = (locale: Locale) => {
- const [t, setT] = useState(null);
- const [page, setPage] = useState(1);
- const [keyword, setKeyword] = useState("");
-
- const pageSize = QUERY_DEFAULT_LIMIT;
- const currentPageIndex = page - 1;
- const paginationValue: PaginationState = {
- pageSize,
- pageIndex: currentPageIndex,
- };
-
- const updateKeywordFn = useCallback(
- (newKeyword: string) => {
- setKeyword(newKeyword.trim());
- setPage(1);
- },
- [setKeyword],
- );
-
- const handleChangeKeyword = useDebounceCallback(
- updateKeywordFn,
- INPUT_DEBOUNCE_INTERVAL,
- );
-
- const handleChangePagination: OnChangeFn = (pagination) => {
- if (typeof pagination === "function") {
- const newPagination = pagination(paginationValue);
-
- setPage(newPagination.pageIndex + 1);
- } else {
- setPage(pagination.pageIndex + 1);
- }
- };
-
- const normalizeData = (fetchData: LeaderboardResponse | null) =>
- (fetchData?.data ?? []).filter((data) => ![1, 2, 3].includes(data.rank));
-
- const fetchFn = useCallback(async () => {
- const res = await api.fetchLeaderboard({
- page,
- pageSize,
- filterByReferralCode: keyword,
- });
- return res.json();
- }, [page, pageSize, keyword]);
-
- const {
- data: fetchData,
- loading: fetchLoading,
- error: fetchError,
- } = useFetch({
- fetchFn,
- polling: {
- enabled: true,
- interval: DATA_POOL_INTERVAL,
- },
- });
-
- const columns = useMemo(() => LEADERBOARD_COLUMNS, []);
- const [rowCount, setRowCount] = useState(
- fetchData?.meta.total_items ?? 0,
- );
-
- const data = normalizeData(fetchData);
-
- const table = useReactTable({
- data,
- columns,
- getCoreRowModel: getCoreRowModel(),
- state: {
- pagination: paginationValue,
- },
- rowCount,
- onPaginationChange: handleChangePagination,
- manualPagination: true,
- });
-
- const loading = fetchLoading || t === null;
- const success = t !== null && !loading && !fetchError;
- const error = !loading && fetchError;
-
- const getStatus = () => {
- switch (true) {
- case success:
- return "success";
- case !!error:
- return "error";
- case !!loading:
- return "loading";
- default:
- return "idle";
- }
- };
-
- useEffect(() => {
- if (!loading && fetchData?.meta.total_items)
- setRowCount(fetchData.meta.total_items);
- }, [loading, fetchData?.meta.total_items]);
-
- useEffect(() => {
- const loadTranslation = async () => {
- const tFn = await createTranslator(locale);
- setT(() => tFn); // ← Use function updater to set a function
- };
-
- loadTranslation();
- }, [locale]);
-
- return {
- handleChangeKeyword,
- table,
- getStatus,
- error,
- t,
- };
-};
diff --git a/website/src/components/features/quests/shill/leaderboard/leaderboard-table/LeaderboardTable.tsx b/website/src/components/features/quests/shill/leaderboard/leaderboard-table/LeaderboardTable.tsx
deleted file mode 100644
index f839ef0..0000000
--- a/website/src/components/features/quests/shill/leaderboard/leaderboard-table/LeaderboardTable.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { DataTable } from "@/components/ui/react/composite/data-table/DataTable";
-
-import { useLeaderboardTable } from "./Hook";
-import type { Locale } from "@/utils/i18n";
-import { Input } from "@/components/ui/react/Input";
-
-interface LeaderboardTableProps {
- locale: Locale;
-}
-
-const LeaderboardTable = ({ locale }: LeaderboardTableProps) => {
- const { handleChangeKeyword, getStatus, table, error, t } =
- useLeaderboardTable(locale);
-
- return (
- <>
-
- Search your entry
-
- {
- const newKeyword = e.target.value;
-
- handleChangeKeyword(newKeyword);
- }}
- />
-
-
- Error: {error && error.message}
- ),
- }}
- withControls
- t={t}
- />
- >
- );
-};
-
-export default LeaderboardTable;
diff --git a/website/src/components/features/quests/shill/rules/Card.astro b/website/src/components/features/quests/shill/rules/Card.astro
deleted file mode 100644
index f3bc926..0000000
--- a/website/src/components/features/quests/shill/rules/Card.astro
+++ /dev/null
@@ -1,21 +0,0 @@
----
-import Separator from "@/components/ui/Separator.astro";
-import { applyStyles } from "@/utils/apply-styles";
-
-export interface Props {
- class?: string;
-}
-
-const { class: className } = Astro.props;
----
-
-
-
-
-
-
diff --git a/website/src/components/features/quests/shill/rules/Rules.astro b/website/src/components/features/quests/shill/rules/Rules.astro
deleted file mode 100644
index 5de515e..0000000
--- a/website/src/components/features/quests/shill/rules/Rules.astro
+++ /dev/null
@@ -1,64 +0,0 @@
----
-import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
-import Card from "./Card.astro";
-
-const locale = getLocaleFromUrl(Astro.url.pathname);
-const t = await createTranslator(locale);
----
-
-
-
- {t("quests.shill.rules.title")}
-
-
-
-
-
-
- {t("quests.shill.rules.goal.title")}
-
-
- {t("quests.shill.rules.goal.content")}
-
-
-
-
-
- {t("quests.shill.rules.prize.title")}
-
-
- {
- t("quests.shill.rules.prize.content").map((val: string) => (
- {val}
- ))
- }
-
-
-
-
-
- {t("quests.shill.rules.win.title")}
-
-
- {t("quests.shill.rules.win.content")}
-
-
-
-
-
-
- {t("quests.shill.rules.win.card.title")}
-
-
-
-
- {t("quests.shill.rules.win.card.content_one")}
-
-
-
- {t("quests.shill.rules.win.card.content_two")}
-
-
-
-
-
diff --git a/website/src/components/features/technology/ArchitectureSection.astro b/website/src/components/features/technology/ArchitectureSection.astro
new file mode 100644
index 0000000..4501a7b
--- /dev/null
+++ b/website/src/components/features/technology/ArchitectureSection.astro
@@ -0,0 +1,93 @@
+---
+import SectionWrapper from "./SectionWrapper.astro";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+ {t("technology.architecture.cards.signatures.title")}
+
+
+ {t("technology.architecture.cards.signatures.body")}
+
+
+
+
+ {t("technology.architecture.cards.network_layer.title")}
+
+
+ {t("technology.architecture.cards.network_layer.body")}
+
+
+
+
+ {t("technology.architecture.cards.scale.title")}
+
+
+ {t("technology.architecture.cards.scale.body")}
+
+
+
+
+
+
diff --git a/website/src/components/features/technology/ConsensusSection.astro b/website/src/components/features/technology/ConsensusSection.astro
new file mode 100644
index 0000000..6a593af
--- /dev/null
+++ b/website/src/components/features/technology/ConsensusSection.astro
@@ -0,0 +1,39 @@
+---
+import SectionWrapper from "./SectionWrapper.astro";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+ {t("technology.consensus.body")}
+
+
+
+
+
diff --git a/website/src/components/features/technology/CryptographySection.astro b/website/src/components/features/technology/CryptographySection.astro
new file mode 100644
index 0000000..92dd41c
--- /dev/null
+++ b/website/src/components/features/technology/CryptographySection.astro
@@ -0,0 +1,253 @@
+---
+import SectionWrapper from "./SectionWrapper.astro";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+ {t("technology.cryptography.columns.meaning.title")}
+
+
+ {t("technology.cryptography.columns.meaning.body")}
+
+
+
+
+ {t("technology.cryptography.columns.urgency.title")}
+
+
+ {t("technology.cryptography.columns.urgency.body")}
+
+
+
+
+
+
+
+
+
+
+
+ {t("technology.cryptography.table.headers.property")}
+
+ {t("technology.cryptography.table.headers.ecdsa")}
+
+
+ {t("technology.cryptography.table.headers.mldsa")}
+
+
+
+
+ {t("technology.cryptography.table.rows.quantum_resistant")}
+
+ ✗
+ ✓
+
+
+
+ {t("technology.cryptography.table.rows.nist_approved")}
+
+ ✗
+ ✓
+
+
+
+ {t("technology.cryptography.table.rows.security_level")}
+
+
+ {t("technology.cryptography.table.values.ecdsa_security")}
+
+
+ {t("technology.cryptography.table.values.mldsa_security")}
+
+
+
+
+ {t("technology.cryptography.table.rows.signature_scheme")}
+
+
+ {t("technology.cryptography.table.values.ecdsa_scheme")}
+
+
+ {t("technology.cryptography.table.values.mldsa_scheme")}
+
+
+
+
+ {t("technology.cryptography.table.rows.shor_vulnerable")}
+
+ ✓
+ ✗
+
+
+
+
+
diff --git a/website/src/components/features/technology/CtaSection.astro b/website/src/components/features/technology/CtaSection.astro
new file mode 100644
index 0000000..92e1360
--- /dev/null
+++ b/website/src/components/features/technology/CtaSection.astro
@@ -0,0 +1,110 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+ {t("technology.cta.title")}
+
+
+ {t("technology.cta.sub")}
+
+
+
+
+
diff --git a/website/src/components/features/technology/HeroBanner.astro b/website/src/components/features/technology/HeroBanner.astro
new file mode 100644
index 0000000..4038ecc
--- /dev/null
+++ b/website/src/components/features/technology/HeroBanner.astro
@@ -0,0 +1,482 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+ {t("technology.hero_banner.eyebrow")}
+
+
+ {t("technology.hero_banner.title_line1")} {
+ t("technology.hero_banner.title_line2")
+ }
+
+
+ {t("technology.hero_banner.sub")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/technology/ScalabilitySection.astro b/website/src/components/features/technology/ScalabilitySection.astro
new file mode 100644
index 0000000..c48672d
--- /dev/null
+++ b/website/src/components/features/technology/ScalabilitySection.astro
@@ -0,0 +1,85 @@
+---
+import SectionWrapper from "./SectionWrapper.astro";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+ {t("technology.scalability.stat.label")}
+
+
+ {t("technology.scalability.stat.value")}
+
+
+ {t("technology.scalability.stat.sub")}
+
+
+
+ {t("technology.scalability.description")}
+
+
+
+
diff --git a/website/src/components/features/technology/SectionWrapper.astro b/website/src/components/features/technology/SectionWrapper.astro
new file mode 100644
index 0000000..134df42
--- /dev/null
+++ b/website/src/components/features/technology/SectionWrapper.astro
@@ -0,0 +1,94 @@
+---
+interface Props {
+ id: string;
+ title: string;
+ subtitle: string;
+ content?: string;
+}
+
+const { id, title, subtitle, content } = Astro.props;
+---
+
+
+
+ {title}
+ {subtitle}
+ {content && {content}
}
+
+
+
+
+
diff --git a/website/src/components/features/wallet/AdvantagesSection.astro b/website/src/components/features/wallet/AdvantagesSection.astro
new file mode 100644
index 0000000..3ef934e
--- /dev/null
+++ b/website/src/components/features/wallet/AdvantagesSection.astro
@@ -0,0 +1,87 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+ {t("wallet.advantage.eyebrow")}
+
+
+ {t("wallet.advantage.heading")}
+
+
+
+
+ {t("wallet.advantage.body")}
+
+
+
+
+
+
diff --git a/website/src/components/features/wallet/CtaSection.astro b/website/src/components/features/wallet/CtaSection.astro
new file mode 100644
index 0000000..d6d1fd5
--- /dev/null
+++ b/website/src/components/features/wallet/CtaSection.astro
@@ -0,0 +1,144 @@
+---
+import { APP_LINKS } from "@/constants/app-links";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+ {t("wallet.cta.title")}
+
+
+ {t("wallet.cta.sub")}
+
+
+
+ {t("wallet.cta.note")}
+
+
+
+
diff --git a/website/src/components/features/wallet/FeaturesSection.astro b/website/src/components/features/wallet/FeaturesSection.astro
new file mode 100644
index 0000000..1b214c7
--- /dev/null
+++ b/website/src/components/features/wallet/FeaturesSection.astro
@@ -0,0 +1,202 @@
+---
+import { Image } from "astro:assets";
+
+import checkphrases from "@/assets/wallet/checkphrases.png";
+import encryptYourFunds from "@/assets/wallet/encrypt-your-funds.png";
+import reversibleTransactions from "@/assets/wallet/reversible-transactions.png";
+import highSecurityAccounts from "@/assets/wallet/high-security-accounts.png";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+
+
+
+
01
+
+ {t("wallet.features.cards.reversible.title")}
+
+
+ {t("wallet.features.cards.reversible.body")}
+
+
+
+
+
+
+
+
+
+
02
+
+ {t("wallet.features.cards.checkphrases.title")}
+
+
+ {t("wallet.features.cards.checkphrases.body")}
+
+
+
+
+
+
+
+
+
+
03
+
+ {t("wallet.features.cards.high_security.title")}
+
+
+ {t("wallet.features.cards.high_security.body")}
+
+
+
+
+
+
+
+
+
+
04
+
+ {t("wallet.features.cards.encrypt.title")}
+
+
+ {t("wallet.features.cards.encrypt.body")}
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/wallet/HeroBanner.astro b/website/src/components/features/wallet/HeroBanner.astro
new file mode 100644
index 0000000..a8488f0
--- /dev/null
+++ b/website/src/components/features/wallet/HeroBanner.astro
@@ -0,0 +1,395 @@
+---
+import { APP_LINKS } from "@/constants/app-links";
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+ {t("wallet.hero_banner.eyebrow")}
+
+
+ {t("wallet.hero_banner.title")}
+
+
+ {t("wallet.hero_banner.sub")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ML-DSA-87
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/src/components/features/wallet/IssuesSection.astro b/website/src/components/features/wallet/IssuesSection.astro
new file mode 100644
index 0000000..87d2069
--- /dev/null
+++ b/website/src/components/features/wallet/IssuesSection.astro
@@ -0,0 +1,134 @@
+---
+import { createTranslator, getLocaleFromUrl } from "@/utils/i18n";
+
+const locale = getLocaleFromUrl(Astro.url.pathname);
+const t = await createTranslator(locale);
+---
+
+
+
+
+
+ {t("wallet.issues.eyebrow")}
+
+
+ {t("wallet.issues.heading")}
+
+
+ {t("wallet.issues.body")}
+
+
+
+
+ {t("wallet.issues.stats.tps.value")}
+
+
+ {t("wallet.issues.stats.tps.label")}
+
+
+
+
+ {t("wallet.issues.stats.security.value")}
+
+
+ {t("wallet.issues.stats.security.label")}
+
+
+
+
+ {t("wallet.issues.stats.migration.value")}
+
+
+ {t("wallet.issues.stats.migration.label")}
+
+
+
+
+
+
+
diff --git a/website/src/components/features/whitepaper/WhitepaperHeader.astro b/website/src/components/features/whitepaper/WhitepaperHeader.astro
index b34387a..ee5fc91 100644
--- a/website/src/components/features/whitepaper/WhitepaperHeader.astro
+++ b/website/src/components/features/whitepaper/WhitepaperHeader.astro
@@ -46,7 +46,7 @@ const displayDate = updatedDate ?? publishedDate;
{title}
diff --git a/website/src/components/layout/Layout.astro b/website/src/components/layout/Layout.astro
index 2506426..8e24f07 100644
--- a/website/src/components/layout/Layout.astro
+++ b/website/src/components/layout/Layout.astro
@@ -1,12 +1,13 @@
---
import "../../styles/global.css";
-import "@fontsource/prompt/200.css";
-import "@fontsource/prompt/300.css";
-import "@fontsource/prompt/400.css";
-import "@fontsource/prompt/600.css";
-import "@fontsource/prompt/700.css";
-import "@fontsource/prompt/900.css";
-import "@fontsource/inter/900.css";
+
+// Main fonts
+import "@fontsource/geist/300.css";
+import "@fontsource/geist/400.css";
+import "@fontsource/geist/500.css";
+import "@fontsource/geist-mono/300.css";
+import "@fontsource/geist-mono/400.css";
+import "@fontsource/geist-mono/500.css";
// Whitepapers Fonts
import "@fontsource/ibm-plex-sans/400.css";
@@ -32,7 +33,7 @@ import {
import { generateBreadcrumbs } from "@/utils/build-json-ld";
import { SITE_NAVIGATIONS } from "@/constants/site-navigations";
import CookieConsent from "@/components/ui/CookieConsent.astro";
-import Toast from "../ui/Toast.astro";
+import Toast from "@/components/ui/Toast.astro";
import env from "@/config";
interface Props extends SEOProps {
@@ -93,7 +94,7 @@ const breadcrumbs = generateBreadcrumbs({
titleTemplate={undefined}
/>
-
+
+ -->
diff --git a/website/src/components/layout/footer/Footer.astro b/website/src/components/layout/footer/Footer.astro
index 2786748..478bf9a 100644
--- a/website/src/components/layout/footer/Footer.astro
+++ b/website/src/components/layout/footer/Footer.astro
@@ -1,14 +1,5 @@
---
-import BrandLogo from "@/assets/brand/brand-logo.svg";
-import BrandName from "@/assets/brand/brand-name.svg";
-
-import LanguageSwitcher from "@/components/ui/LanguageSwitcher.astro";
-import Separator from "@/components/ui/Separator.astro";
-import SiteSocials from "@/components/ui/SiteSocials.astro";
-import SphereDecoration from "@/components/ui/SphereDecoration.astro";
-import SubscribeForm from "@/components/ui/SubscribeForm.astro";
import { FOOTER_NAVIGATIONS } from "@/constants/footer-navigations";
-
import { applyStyles } from "@/utils/apply-styles";
import {
createTranslator,
@@ -28,116 +19,74 @@ const isCurrentPage = (href: string) =>