diff --git a/messages/en.json b/messages/en.json
index 403ec079fe2536ac90fa71d2a999689ab07434dc..a4521db188472ac0989d92a25250efea8de822ce 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -37,7 +37,7 @@
"featureFast": "Fast",
"featureFastText": "Hive has 3 second block times with transactions confirmed within milliseconds due to one-block irreversibility, allowing for a seamless experience.",
"featureScalable": "Scalable",
- "featureScalableText": "Efficiency is key. Hive is optimized for sustainability and flexibility with layered solutions.",
+ "featureScalableText": "Efficiency is key. Hive is optimized for sustainability and flexibility with layered solutions. Nodes can run on modest hardware, keeping the network accessible to all.",
"featurePowerful": "Powerful",
"featurePowerfulText": "Hive is a global decentralized network. It is battle-tested by hundreds of apps, communities & projects around the world."
},
diff --git a/src/app/[locale]/about/page.tsx b/src/app/[locale]/about/page.tsx
index 4b581fe1aa1c6713048e20b27d4f507a76b744c9..4b1c9e9a3ef03a4e37aeb7b5bd6dd5b3149122d6 100644
--- a/src/app/[locale]/about/page.tsx
+++ b/src/app/[locale]/about/page.tsx
@@ -5,6 +5,7 @@ import { useTranslations } from 'next-intl';
import { useRouter, usePathname } from '@/i18n/routing';
import { useAssets } from '@/hooks/useAssets';
import { ABOUT_NAVIGATION } from '@/lib/data/navigation';
+import { ABOUT_VIDEOS } from '@/lib/data/videos';
export default function AboutPage() {
const router = useRouter();
@@ -12,6 +13,9 @@ export default function AboutPage() {
const t = useTranslations();
const { getImage } = useAssets();
+ const featuredVideo = ABOUT_VIDEOS.find(v => v.featured);
+ const gridVideos = ABOUT_VIDEOS.filter(v => !v.featured);
+
return (
@@ -59,6 +63,56 @@ export default function AboutPage() {
{t('about.featurePowerfulText')}
+
+ {/* Video Showcase */}
+
+
+ Learn More.
+
+
+
+
+ {/* Featured Video */}
+ {featuredVideo && (
+
+
+ VIDEO
+
+
{featuredVideo.title}
+
+ {featuredVideo.description}
+
+
+ )}
+
+ {/* Grid of Additional Videos */}
+ {gridVideos.length > 0 && (
+
+ {gridVideos.map((video) => (
+
+
+ VIDEO
+
+
{video.title}
+
{video.description}
+
+ ))}
+
+ )}
+
+
diff --git a/src/app/[locale]/core-dev-meetings/page.tsx b/src/app/[locale]/core-dev-meetings/page.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..950eb9b4e83ab80accae4e6dbec3ef638d748395
--- /dev/null
+++ b/src/app/[locale]/core-dev-meetings/page.tsx
@@ -0,0 +1,90 @@
+'use client';
+
+import React from 'react';
+import { useTranslations } from 'next-intl';
+import { CORE_DEV_MEETINGS } from '@/lib/data/coredevmeetings';
+
+export default function CoreDevMeetingsPage() {
+ const t = useTranslations();
+
+ // Get the latest meeting (first in the array) and the next two
+ const latestMeeting = CORE_DEV_MEETINGS[0];
+ const gridMeetings = CORE_DEV_MEETINGS.slice(1, 3);
+
+ return (
+
+
+ {/* Hero Section */}
+
+
+ Core Dev Meetings.
+
+
+ Watch recordings of Hive core developer meetings to stay updated on the latest technical developments and discussions.
+
+
+
+ {/* Meetings Section */}
+
+
+
+ Latest Meetings.
+
+
+
+
+ {/* Featured Video - Latest Meeting */}
+ {latestMeeting && (
+
+
+ VIDEO
+
+
{latestMeeting.title}
+
+ The most recent core developer meeting discussing Hive blockchain development, updates, and technical decisions.
+
+
+ )}
+
+ {/* Grid of Recent Meetings */}
+ {gridMeetings.length > 0 && (
+
+ {gridMeetings.map((meeting) => (
+
+ ))}
+
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx
index bfa43829359f87a8c10bc655ecf8ceab2878f80f..8b1eae33ef7de179826e6eff01225b21baf836f6 100644
--- a/src/app/[locale]/page.tsx
+++ b/src/app/[locale]/page.tsx
@@ -47,12 +47,15 @@ export default function HomePage() {
-
+
{/* Ecosystem */}
-
+
{/* No fees */}
diff --git a/src/components/ScrollIndicator.tsx b/src/components/ScrollIndicator.tsx
index 466c109e60065b71d53b8d3c735c010e3b688815..17a0f628de87cbc884b8387cf02704c09411744f 100644
--- a/src/components/ScrollIndicator.tsx
+++ b/src/components/ScrollIndicator.tsx
@@ -2,13 +2,38 @@ import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
-interface ScrollIndicatorProps extends React.HTMLAttributes
{}
+interface ScrollIndicatorProps extends React.HTMLAttributes {
+ scrollToSelector?: string;
+}
+
+export const ScrollIndicator: React.FC = ({
+ className,
+ scrollToSelector,
+ onClick,
+ ...props
+}) => {
+ const handleClick = (e: React.MouseEvent) => {
+ if (scrollToSelector) {
+ const element = document.querySelector(scrollToSelector);
+ if (element) {
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' });
+ }
+ }
+
+ if (onClick) {
+ onClick(e);
+ }
+ };
-export const ScrollIndicator: React.FC = ({ className, ...props }) => {
return (
-
+
diff --git a/src/components/mobile-menu/MobileMenu.tsx b/src/components/mobile-menu/MobileMenu.tsx
index 336b72294419d704f23a8857de512437fd20f125..81df49be717fe39cccac589ce84d99561d52349a 100644
--- a/src/components/mobile-menu/MobileMenu.tsx
+++ b/src/components/mobile-menu/MobileMenu.tsx
@@ -2,7 +2,7 @@
import React from 'react';
import { useMainStore } from '@/store/useMainStore';
-import { Navigation } from '@/components/navigation/Navigation';
+import { MobileNavigation } from '@/components/navigation/MobileNavigation';
interface MobileMenuProps extends React.HTMLAttributes
{
items?: any[];
@@ -24,28 +24,32 @@ export const MobileMenu: React.FC = ({
return (
-
+ {/* Navigation overlay */}
+
+ setIsMobileActive(false)}
+ />
+
+
+ {/* Hamburger button */}
+
-
-
-
-
- *]:text-center [&>*]:py-2.5 [&>*]:px-0 [&>*]:w-full -mt-[200px] bg-[#f0f0f8]`}
- items={items}
- onClicked={() => setIsMobileActive(false)}
- />
);
diff --git a/src/components/navigation/MobileNavigation.tsx b/src/components/navigation/MobileNavigation.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..75704155960e8ba203b725bf7bf7ddc40b21061d
--- /dev/null
+++ b/src/components/navigation/MobileNavigation.tsx
@@ -0,0 +1,157 @@
+'use client';
+
+import React, { useState } from 'react';
+import { Link } from '@/i18n/routing';
+import { ChevronDown } from 'lucide-react';
+import { Button } from '@/components/ui/button';
+
+interface NavigationChild {
+ to?: string;
+ name?: string;
+ description?: string;
+}
+
+interface NavigationItemType {
+ to?: string;
+ name?: string;
+ isButton?: boolean;
+ children?: NavigationChild[];
+}
+
+interface MobileNavigationProps {
+ items: NavigationItemType[];
+ onClicked?: () => void;
+}
+
+export const MobileNavigation: React.FC
= ({ items, onClicked }) => {
+ const [openIndex, setOpenIndex] = useState(null);
+
+ const toggleSection = (index: number) => {
+ setOpenIndex(openIndex === index ? null : index);
+ };
+
+ const handleLinkClick = () => {
+ if (onClicked) onClicked();
+ };
+
+ const go = (url: string) => {
+ window.open(url, '_blank');
+ if (onClicked) onClicked();
+ };
+
+ return (
+
+ {items.map((item, index) => {
+ // Items with children (accordion sections)
+ if (item.children && item.children.length > 0) {
+ const isOpen = openIndex === index;
+
+ return (
+
+
toggleSection(index)}
+ className={`w-full flex items-center justify-between py-4 px-0 text-left text-lg font-medium bg-transparent border-none cursor-pointer transition-colors ${
+ isOpen ? 'text-[#e31337]' : 'text-black hover:text-[#e31337]'
+ }`}
+ >
+ {item.name}
+
+
+
+ {isOpen && (
+
+ {item.children.map((child, childIndex) => (
+
+ ))}
+
+ )}
+
+ );
+ }
+
+ // Regular button items
+ if (item.isButton && item.to) {
+ return (
+
+ go(item.to!)}
+ >
+ {item.name}
+
+
+ );
+ }
+
+ // Regular link items
+ if (item.to && (item.to.includes('https://') || item.to.includes('mailto'))) {
+ return (
+
+ );
+ }
+
+ if (item.to) {
+ return (
+
+
+ {item.name}
+
+
+ );
+ }
+
+ return null;
+ })}
+
+ );
+};
diff --git a/src/components/navigation/Navigation.tsx b/src/components/navigation/Navigation.tsx
index 5eb3ca94a0d2fa95ab98ed7ccc94dc76c6fd11ef..571e5e35a829c7f95ac7b6e3fb71ffe14f763ff2 100644
--- a/src/components/navigation/Navigation.tsx
+++ b/src/components/navigation/Navigation.tsx
@@ -9,7 +9,6 @@ import {
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
- NavigationMenuViewport,
} from '@/components/ui/navigation-menu';
import { Link } from '@/i18n/routing';
@@ -44,21 +43,24 @@ export const Navigation: React.FC = ({
return items.some(item => item.children && item.children.length > 0);
}, [items]);
+ // Check if this is mobile menu (flex-col indicates mobile)
+ const isMobileMenu = className?.includes('flex-col');
+
// Navigation with dropdowns
if (hasDropdowns) {
return (
-
-
-
+
+
+
{items.map((item, index) => {
// Dropdown menu items
if (item.children && item.children.length > 0) {
return (
-
-
+
+
{item.name}
-
+
{item.children.map((child, childIndex) => (
@@ -67,6 +69,7 @@ export const Navigation: React.FC = ({
href={child.to}
target="_blank"
rel="nofollow noopener noreferrer"
+ onClick={onClicked}
className="block no-underline rounded-md py-3 px-4 transition-colors duration-100 ease-in hover:bg-[#f5f5f5] focus:outline-none focus:bg-[#f5f5f5]"
>
@@ -82,6 +85,7 @@ export const Navigation: React.FC
= ({
@@ -105,7 +109,7 @@ export const Navigation: React.FC = ({
// Regular navigation items
return (
-
+
= ({
);
})}
-
);
diff --git a/src/lib/data/coredevmeetings.ts b/src/lib/data/coredevmeetings.ts
new file mode 100644
index 0000000000000000000000000000000000000000..18e60515e6d554fb9b069c3b69d47272e1620d9d
--- /dev/null
+++ b/src/lib/data/coredevmeetings.ts
@@ -0,0 +1,58 @@
+export interface ICoreDevMeeting {
+ videoId: string;
+ title: string;
+ meetingNumber?: number;
+}
+
+export const CORE_DEV_MEETINGS: ICoreDevMeeting[] = [
+ {
+ videoId: 'tmnD5duLxcE',
+ title: 'Core Dev Meeting #75',
+ meetingNumber: 75,
+ },
+ {
+ videoId: '1qPy3aR_ivo',
+ title: 'Core Dev Meeting #74',
+ meetingNumber: 74,
+ },
+ {
+ videoId: 'pR-WXe1fKnA',
+ title: 'Core Dev Meeting #73',
+ meetingNumber: 73,
+ },
+ {
+ videoId: 'v4FuoQK0C4s',
+ title: 'Core Dev Meeting #41',
+ meetingNumber: 41,
+ },
+ {
+ videoId: 'wfvLzwnlEms',
+ title: 'Core Dev Meeting #40',
+ meetingNumber: 40,
+ },
+ {
+ videoId: '1iHk9vVOAMY',
+ title: 'Core Dev Meeting #39',
+ meetingNumber: 39,
+ },
+ {
+ videoId: 'ZXpzcXFPqeM',
+ title: 'Core Dev Meeting #38',
+ meetingNumber: 38,
+ },
+ {
+ videoId: 'yrGrvgXAGMw',
+ title: 'Core Dev Meeting #37',
+ meetingNumber: 37,
+ },
+ {
+ videoId: 'uoskscKWT-A',
+ title: 'Core Dev Meeting #36',
+ meetingNumber: 36,
+ },
+ {
+ videoId: 'ikzao9_9Gl4',
+ title: 'Core Dev Meeting #35',
+ meetingNumber: 35,
+ },
+];
diff --git a/src/lib/data/navigation.ts b/src/lib/data/navigation.ts
index 5e1f7f24e521340425ab7f122240c9bafd4bcd6b..d92ec1c5a79dab3b4c5d08545c6070b7866774a7 100644
--- a/src/lib/data/navigation.ts
+++ b/src/lib/data/navigation.ts
@@ -40,6 +40,11 @@ export const NAVIGATION_HEADER_DROPDOWN = [
name: 'Repositories',
description: 'Browser Hive applications and source code',
},
+ {
+ to: 'core-dev-meetings',
+ name: 'Core Dev Meetings',
+ description: 'Watch recordings of core developer meetings',
+ },
],
},
{
diff --git a/src/lib/data/videos.ts b/src/lib/data/videos.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8855a40efbbed704a072645d71386eed6a50db9a
--- /dev/null
+++ b/src/lib/data/videos.ts
@@ -0,0 +1,28 @@
+export interface IVideo {
+ videoId: string;
+ title: string;
+ description: string;
+ featured?: boolean;
+}
+
+export const ABOUT_VIDEOS: IVideo[] = [
+ {
+ videoId: 'llIRm5XxeRA',
+ title: 'To Gas Or Not To Gas?',
+ description:
+ 'Gas fees shape how people experience blockchains. Some ecosystems remove them, others sponsor or hide them, and some make them so tiny they nearly disappear. This session compares four approaches.',
+ featured: true,
+ },
+ {
+ videoId: 'cBjfIJB9XTo',
+ title: 'Chain Culture',
+ description:
+ 'A full day of cross-chain talks, creative showcases, penguins, and pure good vibes at HiveFest 10.',
+ },
+ {
+ videoId: 'oPwuUofvf_0',
+ title: 'HardFork 28 - The Future of Hive',
+ description:
+ "The CoreDev team on HF28, scalability and governance behind Hive's tech engine.",
+ },
+];