diff --git a/public/icons/signal.svg b/public/icons/signal.svg
new file mode 100644
index 0000000..cc07d87
--- /dev/null
+++ b/public/icons/signal.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/review.png b/public/review.png
new file mode 100644
index 0000000..41954b9
Binary files /dev/null and b/public/review.png differ
diff --git a/public/scripts/text-scramble.js b/public/scripts/text-scramble.js
new file mode 100644
index 0000000..0cbf305
--- /dev/null
+++ b/public/scripts/text-scramble.js
@@ -0,0 +1,99 @@
+function applyScrambleEffect() {
+ const glitchTextElements = document.querySelectorAll('.glitch-text');
+ const glitchTextHoverElements = document.querySelectorAll('.glitch-text-hover');
+
+ function animateScramble(element, text, duration = 2000) {
+ const chars = [];
+ element.innerHTML = ''; // Clear the original text
+
+ // Measure the element's width before animation starts
+ const preScrambleWidth = element.offsetWidth;
+ element.style.width = `${preScrambleWidth}px`;
+
+ for (let t = 0; t < text.length; t++) {
+ const span = document.createElement('span');
+
+ // Check if the character is a space, then use to preserve it
+ span.innerHTML = text[t] === ' ' ? ' ' : text[t];
+ chars[t] = span;
+ span.style.display = 'inline-block';
+ element.appendChild(span);
+ }
+
+ const rand = Math.random;
+ const SECONDS = 1000;
+ const FPS = 30;
+ const animationLength = duration;
+
+ function animate3(k) {
+ const kk = k * text.length;
+ for (let i = 0; i < text.length; i++) {
+ if (kk < i) {
+ chars[i].innerHTML = String.fromCharCode(~~(65 + rand() * 26));
+ } else {
+ // Preserve spaces with
+ chars[i].innerHTML = text[i] === ' ' ? ' ' : text[i];
+ }
+ }
+ }
+
+ // Animation loop
+ let start = Date.now();
+ function animate() {
+ const current = Date.now();
+ const time = current - start;
+ const k = time / animationLength;
+
+ if (k < 1) {
+ setTimeout(animate, SECONDS / FPS);
+ animate3(k);
+ } else {
+ // Ensure the final text is revealed once the animation is complete
+ for (let i = 0; i < text.length; i++) {
+ chars[i].innerHTML = text[i] === ' ' ? ' ' : text[i];
+ }
+ // Restore the original width (optional if you want to revert to normal)
+ element.style.width = 'auto';
+ // Allow new hover events after the animation completes
+ element.isAnimating = false;
+ }
+ }
+
+ animate();
+ }
+
+ // Use Intersection Observer to observe when the element comes into view
+ const observer = new IntersectionObserver((entries, observer) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ const element = entry.target;
+ const text = element.innerText;
+ animateScramble(element, text);
+ observer.unobserve(element); // Stop observing after the animation has been triggered
+ }
+ });
+ }, {
+ threshold: 0.1 // Trigger when 10% of the element is visible
+ });
+
+ // Observe each glitchTextElement for when it comes into view
+ glitchTextElements.forEach((element) => {
+ observer.observe(element);
+ });
+
+ glitchTextHoverElements.forEach((element) => {
+ const text = element.innerText;
+
+ element.isAnimating = false;
+
+ element.addEventListener('mouseenter', () => {
+ if (!element.isAnimating) {
+ element.isAnimating = true; // Set flag to prevent re-triggering during animation
+ animateScramble(element, text, 800);
+ }
+ });
+ });
+ }
+
+ document.addEventListener('DOMContentLoaded', applyScrambleEffect);
+
\ No newline at end of file
diff --git a/src/components/AboutFooter.astro b/src/components/AboutFooter.astro
index 199f1f9..6e85303 100644
--- a/src/components/AboutFooter.astro
+++ b/src/components/AboutFooter.astro
@@ -2,114 +2,147 @@
import * as config from "../config.yaml";
import core from "../core.json";
import contributors from "../contributors.json";
-import { getPersonByGH } from "../lib/core.js";
-import PeopleCarousel from "../components/PeopleCarousel.astro";
+import SpeakerGrid from "./SpeakerGrid.astro";
+import SliderTestimonial from "./SliderTestimonial.astro";
+import MembersGrid from "./MembersGrid.astro";
-function findPerson(src) {
- const p = core.people.find((p) =>
- src.refs?.twitter
- ? p.refs?.twitter === src.refs.twitter
- : src.refs?.bsky
- ? p.refs.bsky === src.refs.bsky
- : {}
- );
- if (p) {
- p.ct = src;
- }
- return p;
-}
+// Accept sectionsConfig as a prop
+const {
+ sectionsConfig = [
+ { name: "community", visible: true, order: 1 },
+ { name: "socialLinks", visible: true, order: 2 },
+ { name: "speakers", visible: true, order: 3 },
+ { name: "core contributors", visible: true, order: 4 },
+ { name: "contributors", visible: true, order: 5 },
+ { name: "testimonials", visible: true, order: 6 },
+ { name: "membersGrid", visible: true, order: 7 },
+ { name: "communityPartners", visible: true, order: 8 },
+ ],
+} = Astro.props;
-function personLink(person) {
- return person.refs?.twitter
- ? `https://twitter.com/${person.refs.twitter}`
- : person.refs?.bsky
- ? `https://bsky.app/profile/${person.refs.bsky}`
- : "#";
-}
+console.log(sectionsConfig);
+// Function to sort sections by order
+const sortedSections = sectionsConfig
+ .filter((section) => section.visible)
+ .sort((a, b) => a.order - b.order);
---
-
-
-
-
{config.landing.community}
+
+
{config.landing.community}
+
+ )}
- Speakers
-
- {
- core.people
- .filter((p) => !core.teams["core-team"].includes(p.id))
- .filter((p) => p.imageUrl)
- .map((person) => (
-
- ))
- }
-
-
-
-
- Git Contributors
-
- {
- // filter(p => !core.teams['core-team'].includes(getPersonByGH(p.login)?.id))
- contributors.items.map((contrib) => (
-
+ )}
-
-
+ {section.name === "speakers" && (
+
+
Speakers
+
+
+ )}
+
+ {section.name === "core contributors" && (
+
+
Core Contributors
+
+
+ )}
+
+ {section.name === "contributors" && (
+
+
Contributors
+
+ {contributors.items.map((contrib) => (
+
+ ))}
+
+
+
+ )}
+
+ {section.name === "testimonials" && (
+
+
+ What People Have To Say About US
+
+
+
+ )}
+
+ {section.name === "membersGrid" && (
+
+
Members
+
+
+ )}
+
+ ))
+}
diff --git a/src/components/AboutItemGrid.astro b/src/components/AboutItemGrid.astro
index 14cb84c..6cb53b6 100644
--- a/src/components/AboutItemGrid.astro
+++ b/src/components/AboutItemGrid.astro
@@ -2,236 +2,137 @@
import AboutItem from "../components/AboutItem.astro";
---
-
-
-
-
- General public
- Projects
- Startupers
-
-
- Developers
- Audit companies
- Investors
-
+
+
+
+
+ We cultivate and foster a culture of privacy in web3 making data free
+ and public.
+
+
+ Check our annual reports, infographics, privacy awards, newsletter, and
+ guidelines.
+
+
web3privacy Research
-
-
-
-
-
-
-
- Market stats
-
- -
-
- Like Crunchbase, but free forever
-
-
-
+
+
+
+
+ By developing free and open tools, we empower people to make informed
+ decisions:
+
-
-
-
-
- Privacy Ranking
-
-
-
-
- Scoring and review of current privacy projects
-
+
+
+
+
+
-
-
-
-
-
- Academy
-
- -
- Education for general public how to reach privacy
-
-
-
-
-
-
-
- Research
-
- -
-
- Anual reports, Frameworks, Tools, Books
-
-
-
-
-
-
-
- Data
-
-
-
-
+
+ PRIVACY EXPLORER
+
+ For Projects, Use-case list, Market & Funding info
-
-
-
-
-
-
-
- Advocacy
-
- -
-
- Branding “decentralization = privacy”
-
-
-
-
-
-
-
- Events
-
-
-
-
- Meetups, Summits, Hackathons, Camps
-
+
+
+
+
-
-
-
-
-
- Ecosystems collaboration
-
- -
- Networks, Alliances, Media
-
-
-
-
-
-
- Standartisation
-
- -
-
- Privacy-features, security audit (example)
-
-
-
-
-
-
-
- Incubation
-
-
-
-
Product managers facilitation, Business sustainability
+
+
+
+ HACKATHON IDEA GENERATOR
+
+
+
Helps developers build applications that address real-world
+ problems, that people will actually use.
-
-
-
-
-
-
- GENERAL PUBLIC
-
-
- Milions of educated users
- Higher privacy culture
-
+
+
+
+
-
-
- PROJECTS
+
+
+ WEEK IN PRIVACY
+
+
Weekly newsletter with round-up of the most important news
+ happening around privacy in Web3
-
- Better privacy features
- New use-cases
- Efficient demos
-
-
-
-
- SECURITY AUDIT COMPANIES
-
-
- New “privacy audit” category
- Significant growth of audited projects.
-
-
-
-
-
-
- DEVELOPERS
-
-
- More devs building privacy
- More sustainable projects.
-
-
-
-
- STARTUPERS
-
-
- More privacy-oriented projects
- Longer runway
-
-
-
+
+
+
+
+
+
+
+
+
+ We make privacy accessible for everyone, empowering people to learn and
+ implement best practices effectively.
+
+
+ From mentoring at hackathons, guidelines for developers, and the
+ Cypherpunk Academy - we offer training, incubation, and acceleration
+ programs.
+
+
Privacy Academy
+
+
+
diff --git a/src/components/SliderTestimonial.astro b/src/components/SliderTestimonial.astro
new file mode 100644
index 0000000..6828b84
--- /dev/null
+++ b/src/components/SliderTestimonial.astro
@@ -0,0 +1,176 @@
+---
+const testimonials = [
+ {
+ author: "Matteo",
+ text: `balance between Transparency and Privacy, accountable and unaccountable, manifest and secret, convex and concave, 1 and 0 is one of the most fun puzzles.`,
+ imageUrl: "/review.png",
+ },
+ {
+ author: "Jane",
+ text: `This platform has opened my eyes to the potential of blockchain technology in a way that I never imagined. The community is vibrant and full of innovation.`,
+ imageUrl: "/review.png",
+ },
+ {
+ author: "Alex",
+ text: `It's amazing to see how much transparency can coexist with privacy, and this is the best representation of how it can work. Great work!`,
+ imageUrl: "/review.png",
+ },
+];
+
+let currentTestimonial = 0;
+---
+
+
+
+
+
+
+
+
+
+
+ {testimonials[currentTestimonial].author}:
+
+
+ "{testimonials[currentTestimonial].text}"
+
+
+
+
+
+
+
+
+
+
+ {
+ testimonials.map((_, index) => (
+
+ ))
+ }
+
+
+
+
+
diff --git a/src/components/SpeakerGrid.astro b/src/components/SpeakerGrid.astro
new file mode 100644
index 0000000..d8d008e
--- /dev/null
+++ b/src/components/SpeakerGrid.astro
@@ -0,0 +1,49 @@
+---
+const { people, team } = Astro.props;
+
+// Filter the people and limit the results to 12
+const filteredPeople = people
+ .filter((p) => !team.includes(p.id))
+ .filter((p) => p.imageUrl)
+ .slice(0, 12); // Limit to the first 12 people
+
+function personLink(person) {
+ return person.refs?.twitter
+ ? `https://twitter.com/${person.refs.twitter}`
+ : person.refs?.bsky
+ ? `https://bsky.app/profile/${person.refs.bsky}`
+ : "#";
+}
+
+function truncateCaption(caption) {
+ if (!caption) return "";
+ const words = caption.split(" ");
+ if (words.length > 10) {
+ return words.slice(0, 20).join(" ") + "...";
+ }
+ return caption;
+}
+---
+
+
+ {filteredPeople.map((person) => (
+
+
+
+
+
+
{person.name}
+ {person.refs && person.refs.twitter && (
+
@{person.refs.twitter}
+ )}
+
{truncateCaption(person.caption)}
+
+
+ ))}
+
diff --git a/src/config.yaml b/src/config.yaml
index b4c2795..08749e0 100644
--- a/src/config.yaml
+++ b/src/config.yaml
@@ -22,7 +22,7 @@ header:
link: news
- name: Docs
link: docs
- - name: Membership
+ - name: Get Involved
link: membership
url: /membership
#- name: Manifesto
diff --git a/src/layouts/base.astro b/src/layouts/base.astro
index 18c93b3..e1989e5 100644
--- a/src/layouts/base.astro
+++ b/src/layouts/base.astro
@@ -155,7 +155,9 @@ function genHeading(str) {
{config.hero.text}
@@ -167,7 +169,6 @@ function genHeading(str) {
<>
- {/*
*/}
{genHeading(title)}
@@ -176,7 +177,7 @@ function genHeading(str) {
-
{subtext}
+ {subtext}
>
)
@@ -188,40 +189,79 @@ function genHeading(str) {