diff --git a/app/teknav-home.jsx b/app/teknav-home.jsx
new file mode 100644
index 0000000..14311a0
--- /dev/null
+++ b/app/teknav-home.jsx
@@ -0,0 +1,644 @@
+// teknav-home.jsx — Homepage (ES module)
+import { useState, useEffect, useRef } from 'react';
+import { TeknavData } from './teknav-data.js';
+import { useNav, useAuth, AuthorAvatar, CategoryBadge, TypeBadge, NewsletterForm, StreakWidget, ContinueReadingBar, ReadingListModal, pillBtn, useViewportPrefetch } from './teknav-ui.jsx';
+import { DiagramRenderer } from './teknav-diagrams.jsx';
+import { contentApi } from './src/lib/content-api.js';
+import { engagementApi } from './src/lib/engagement-api.js';
+
+// ── Hero Neural Background ──────────────────────────────────────────────────
+function HeroBackground() {
+ const canvasRef = useRef();
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+ const ctx = canvas.getContext('2d');
+ let raf,t = 0;
+ const palette = [
+ 'rgba(15,107,115,', // deep teal (Teknav brand)
+ 'rgba(196,106,77,', // terracotta
+ 'rgba(47,143,107,' // warm green
+ ];
+ const nodes = Array.from({ length: 32 }, (_, i) => ({
+ x: Math.random() * canvas.width,
+ y: Math.random() * canvas.height,
+ vx: (Math.random() - 0.5) * 0.35,
+ vy: (Math.random() - 0.5) * 0.35,
+ r: Math.random() * 3 + 1.5,
+ color: palette[i % palette.length],
+ phase: Math.random() * Math.PI * 2
+ }));
+
+ const resize = () => {canvas.width = canvas.offsetWidth;canvas.height = canvas.offsetHeight;};
+ resize();
+ window.addEventListener('resize', resize);
+
+ const draw = () => {
+ t += 0.012;
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ nodes.forEach((n) => {
+ n.x += n.vx;n.y += n.vy;
+ if (n.x < 0 || n.x > canvas.width) n.vx *= -1;
+ if (n.y < 0 || n.y > canvas.height) n.vy *= -1;
+ nodes.forEach((m) => {
+ const d = Math.hypot(n.x - m.x, n.y - m.y);
+ if (d < 130) {
+ ctx.beginPath();
+ ctx.moveTo(n.x, n.y);ctx.lineTo(m.x, m.y);
+ ctx.strokeStyle = `rgba(15,107,115,${0.18 * (1 - d / 130)})`;
+ ctx.lineWidth = 0.8;ctx.stroke();
+ }
+ });
+ const pulse = 0.45 + 0.18 * Math.sin(t + n.phase);
+ ctx.beginPath();
+ ctx.arc(n.x, n.y, n.r, 0, Math.PI * 2);
+ ctx.fillStyle = n.color + pulse + ')';
+ ctx.fill();
+ });
+ raf = requestAnimationFrame(draw);
+ };
+ draw();
+ return () => {cancelAnimationFrame(raf);window.removeEventListener('resize', resize);};
+ }, []);
+ return ;
+}
+
+// ── Article Card (grid) ─────────────────────────────────────────────────────
+function ArticleCard({ article, delay = 0, readProgress = null }) {
+ const { navigate } = useNav();
+ const { user } = useAuth();
+ const [vis, setVis] = useState(false);
+ const [listModalOpen, setListModalOpen] = useState(false);
+ const ref = useRef();
+ useViewportPrefetch(ref, article.slug);
+ useEffect(() => {
+ const obs = new IntersectionObserver(([e]) => {if (e.isIntersecting) setVis(true);}, { threshold: 0.1 });
+ if (ref.current) obs.observe(ref.current);
+ return () => obs.disconnect();
+ }, []);
+ const author = TeknavData.authors.find((a) => a.id === article.authorId);
+ const cat = TeknavData.categories.find((c) => c.id === article.category);
+ const showContinue = readProgress !== null && readProgress >= 5 && readProgress <= 95;
+
+ return (
+
navigate('/article/' + article.slug)} style={{
+ background: '#fff', borderRadius: 12, border: '1px solid #E4DDD2',
+ padding: 24, cursor: 'pointer', direction: 'rtl',
+ opacity: vis ? 1 : 0, transform: vis ? 'translateY(0)' : 'translateY(24px)',
+ transition: `opacity 0.5s ${delay}ms, transform 0.5s ${delay}ms, box-shadow 0.2s`,
+ boxShadow: '0 2px 12px rgba(0,0,0,0.04)'
+ }} onMouseEnter={(e) => e.currentTarget.style.boxShadow = '0 8px 32px rgba(0,0,0,0.1)'}
+ onMouseLeave={(e) => e.currentTarget.style.boxShadow = '0 2px 12px rgba(0,0,0,0.04)'}>
+ {/* Diagram thumbnail */}
+
+
+
+
+ {showContinue && (
+ <>
+
+
ادامه مطالعه
+ >
+ )}
+
+
+
+
+ {article.sponsored && Promoted Content}
+ {article.premiumOnly && Premium}
+
+
{article.title}
+
{article.summary.slice(0, 100)}...
+
+
{article.date}
+
+ {author &&
}
+
{article.readTime} دقیقه
+ {user && (
+
+ )}
+
+
+ {listModalOpen &&
setListModalOpen(false)} />}
+ );
+
+}
+
+// ── Featured Article ────────────────────────────────────────────────────────
+function FeaturedArticle({ article }) {
+ const { navigate } = useNav();
+ const ref = useRef();
+ useViewportPrefetch(ref, article.slug);
+ const author = TeknavData.authors.find((a) => a.id === article.authorId);
+ const cat = TeknavData.categories.find((c) => c.id === article.category);
+ return (
+ navigate('/article/' + article.slug)} style={{
+ background: '#fff', borderRadius: 16, border: '1px solid #E4DDD2', padding: 0,
+ cursor: 'pointer', overflow: 'hidden', direction: 'rtl',
+ boxShadow: '0 4px 24px rgba(0,0,0,0.06)',
+ display: 'grid', gridTemplateColumns: '1fr 1fr', minHeight: 280,
+ transition: 'box-shadow 0.2s'
+ }} className="featured-card" onMouseEnter={(e) => e.currentTarget.style.boxShadow = '0 12px 48px rgba(0,0,0,0.12)'}
+ onMouseLeave={(e) => e.currentTarget.style.boxShadow = '0 4px 24px rgba(0,0,0,0.06)'}>
+
+
+
+
+
+ {article.sponsored && Promoted Content}
+ {article.premiumOnly && Premium}
+
+
{article.title}
+
{article.summary}
+
+
+ {author &&
}
+
+
{article.authorName}
+
{article.date} · {article.readTime} دقیقه مطالعه
+
+
+
+
+
+
+
);
+
+}
+
+// ── Resolve an author's profile URL (username from API or static fallback) ───
+function authorProfilePath(author) {
+ const username = author.username || TeknavData.authors.find(a => a.slug === author.slug)?.username;
+ return username ? `/profile/@${username}` : `/author/${author.slug}`;
+}
+
+// ── Authors Section ─────────────────────────────────────────────────────────
+function AuthorsSection() {
+ const { navigate } = useNav();
+ const [authors, setAuthors] = useState(TeknavData.authors);
+
+ useEffect(() => {
+ let cancelled = false;
+ contentApi.listAuthors()
+ .then(items => {
+ if (cancelled || !items?.length) return;
+ // Merge API data with static data to fill missing fields (username, bio, expertise)
+ const merged = items.map(apiAuthor => {
+ const seed = TeknavData.authors.find(a => a.slug === apiAuthor.slug || a.id === apiAuthor.id);
+ return { ...seed, ...apiAuthor, username: apiAuthor.username || seed?.username, bio: seed?.bio || apiAuthor.bio, specialty: seed?.specialty || apiAuthor.specialty };
+ });
+ setAuthors(merged);
+ })
+ .catch(() => {});
+ return () => { cancelled = true; };
+ }, []);
+
+ return (
+
+ نویسندگان تکناو
+ متخصصانی که روایت عمیق فناوری را مینویسند
+
+ {authors.map((author) =>
+
navigate(authorProfilePath(author))} style={{
+ background: '#fff', border: '1px solid #E4DDD2', borderRadius: 12, padding: 20,
+ cursor: 'pointer', textAlign: 'center', transition: 'all 0.2s'
+ }} onMouseEnter={(e) => { e.currentTarget.style.transform = 'translateY(-4px)'; e.currentTarget.style.boxShadow = '0 8px 24px rgba(0,0,0,0.08)'; }}
+ onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = 'none'; }}>
+
+
{author.name}
+
{author.specialty}
+
{author.articleCount} مقاله
+
+ )}
+
+
+ );
+}
+
+// ── Hero Section (light bg, parallax + shimmer) ─────────────────────────────
+function HeroSection({ featured, navigate }) {
+ const wrapRef = useRef();
+ const cardRef = useRef();
+
+ // Subtle parallax tilt on mouse-move (disabled on touch)
+ useEffect(() => {
+ const wrap = wrapRef.current;
+ const card = cardRef.current;
+ if (!wrap || !card) return;
+ const onMove = (e) => {
+ const r = wrap.getBoundingClientRect();
+ const dx = (e.clientX - r.left) / r.width - 0.5;
+ const dy = (e.clientY - r.top) / r.height - 0.5;
+ card.style.transform = `perspective(900px) rotateX(${(-dy * 4).toFixed(2)}deg) rotateY(${(dx * 6).toFixed(2)}deg) translateY(0)`;
+ };
+ const onLeave = () => { card.style.transform = 'perspective(900px) rotateX(0) rotateY(0)'; };
+ wrap.addEventListener('mousemove', onMove);
+ wrap.addEventListener('mouseleave', onLeave);
+ return () => { wrap.removeEventListener('mousemove', onMove); wrap.removeEventListener('mouseleave', onLeave); };
+ }, []);
+
+ return (
+
+ {/* Soft glows tuned for light bg */}
+
+
+ {/* Subtle grid overlay for depth */}
+
+
+
+
+
+
+
+ روایت عمیق فناوری
+
+
+ درک عمیقتر
+
+
+ دنیای فناوری
+
+
+ تحلیلهای علمی، تخصصی و مستقل از پیشرفتهای هوش مصنوعی، علم داده، امنیت سایبری و آینده فناوری.
+
+
+
+
+
+
+
+ {/* Featured card — light theme, parallax tilt, soft shadow */}
+ {featured &&
+
+ {/* Decorative accent stripe */}
+
+
+ ✦
+ مقاله ویژه
+
+
navigate('/article/' + featured.slug)} style={{ fontSize: 18, fontWeight: 700, color: '#0F2A2E', cursor: 'pointer', lineHeight: 1.65, transition: 'color 0.15s', fontFamily: "'PelakFA','Vazirmatn',sans-serif" }}
+ onMouseEnter={(e) => e.currentTarget.style.color = '#0F6B73'}
+ onMouseLeave={(e) => e.currentTarget.style.color = '#0F2A2E'}>
+ {featured.title}
+
+
+ {featured.authorName}
+ ·
+ {featured.type}
+ ·
+ {featured.readTime} دقیقه مطالعه
+
+
+ }
+
+
+ {/* Wave divider for smooth transition into next section */}
+
+
+
+
+ );
+}
+
+// ── Stats Bar ───────────────────────────────────────────────────────────────
+function CountUp({ to, suffix = '', duration = 1400 }) {
+ const [n, setN] = useState(0);
+ const ref = useRef();
+ const started = useRef(false);
+ useEffect(() => {
+ const obs = new IntersectionObserver(([e]) => {
+ if (e.isIntersecting && !started.current) {
+ started.current = true;
+ const start = performance.now();
+ const tick = (now) => {
+ const p = Math.min((now - start) / duration, 1);
+ const eased = 1 - Math.pow(1 - p, 3);
+ setN(Math.round(to * eased));
+ if (p < 1) requestAnimationFrame(tick);
+ };
+ requestAnimationFrame(tick);
+ }
+ }, { threshold: 0.4 });
+ if (ref.current) obs.observe(ref.current);
+ return () => obs.disconnect();
+ }, [to, duration]);
+ // Render Persian digits
+ const fa = String(n).replace(/\d/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[d]);
+ // Add thousands separator (٬ for Persian)
+ const formatted = fa.replace(/\B(?=(\d{3})+(?!\d))/g, '٬');
+ return {formatted}{suffix};
+}
+
+function StatsBar() {
+ const stats = [
+ { label: 'مقاله منتشرشده', to: 75, suffix: '+', icon: '◉' },
+ { label: 'نویسنده فعال', to: 2, suffix: '', icon: '✎' },
+ { label: 'خواننده ماهانه', to: 65000, suffix: '+', icon: '◐' },
+ { label: 'میانگین زمان مطالعه', to: 8, suffix: ' دقیقه', icon: '◷' },
+ ];
+
+ return (
+
+
+ {stats.map((s, i) =>
+
+
{s.icon}
+
+
+
+
{s.label}
+ {i < stats.length - 1 &&
+
+ }
+
+ )}
+
+
);
+
+}
+
+// ── Shared section styles ───────────────────────────────────────────────────
+const sectionTitle = { fontSize: 22, fontWeight: 800, color: '#263238', margin: '0 0 8px', fontFamily: 'Vazirmatn,sans-serif' };
+const sectionSubtitle = { fontSize: 14, color: '#5F6B6D', margin: '0 0 32px', lineHeight: 1.7 };
+
+// ── Homepage ────────────────────────────────────────────────────────────────
+function HomePage() {
+ const { navigate } = useNav();
+ const { user } = useAuth();
+ const [articles, setArticles] = useState(() => contentApi.fallbackArticles());
+ const [personalized, setPersonalized] = useState([]);
+ const [readProgressMap, setReadProgressMap] = useState({});
+
+ useEffect(() => {
+ let cancelled = false;
+ contentApi.listArticles({ limit: 50 })
+ .then((res) => { if (!cancelled) setArticles(res.items ?? []); })
+ .catch(() => {});
+
+ if (user) {
+ contentApi.listArticles({ limit: 12, sort: 'personalized' })
+ .then((res) => { if (!cancelled) setPersonalized(res.items ?? []); })
+ .catch(() => {});
+ engagementApi.getStreaks()
+ .then((data) => {
+ if (cancelled) return;
+ const map = {};
+ (data.continueReading ?? []).forEach(item => {
+ map[item.slug] = Math.round((item.progress ?? 0) * 100);
+ });
+ setReadProgressMap(map);
+ })
+ .catch(() => {});
+ } else {
+ setPersonalized([]);
+ setReadProgressMap({});
+ }
+
+ return () => { cancelled = true; };
+ }, [user]);
+
+ const featured = articles.find((a) => a.featured) || articles[0];
+ const latest = articles.filter((a) => a.id !== featured?.id).slice(0, 6);
+ const popular = [...articles].sort((a, b) => b.views - a.views).slice(0, 4);
+ const deep = articles.filter((a) => a.type === 'تحلیل عمیق').slice(0, 3);
+ const thisWeek = [...articles].sort((a, b) => new Date(b.dateEn) - new Date(a.dateEn)).slice(0, 6);
+ const openclawCluster = articles.filter((a) => a.seriesSlug === 'openclaw-series');
+ const securityCluster = articles.filter((a) => a.category === 'security').slice(0, 5);
+
+ return (
+
+ {/* Personalized Bar / Streak */}
+ {user && (
+
+ )}
+
+ {/* Hero */}
+
+
+
+
+
+ {/* Personalized Feed */}
+ {personalized.length > 0 && (
+
+ پیشنهاد برای شما
+ بر اساس علایق و تاریخچه مطالعه شما
+
+ {personalized.map((a, i) =>
)}
+
+
+ )}
+
+ {/* Featured article */}
+ {featured &&
+
+ مقاله منتخب
+ عمیقترین تحلیل این هفته
+
+
+ }
+
+ {/* Latest */}
+
+
+
تازهترین خبرها
+
+
+ آخرین تحلیلها و مقالات تکناو
+
+ {latest.map((a, i) =>
)}
+
+
+
+ {/* Deep analysis */}
+ {deep.length > 0 &&
+
+ تحلیلهای عمیق
+ بررسیهای تخصصی و مستند
+
+
+ }
+
+ {/* Popular */}
+
+ محبوبترینها
+ پرخوانندهترین مقالات تکناو
+
+ {popular.map((a, i) =>
)}
+
+
+
+ {/* This Week */}
+
+
+
+
+
این هفته در تکناو
+
+
+
+ تازهترین تحلیلهای خرداد ۱۴۰۵
+
+ {thisWeek.map((a, i) =>
)}
+
+
+
+ {/* OpenClaw Cluster */}
+ {openclawCluster.length > 0 && (
+
+
+
+ ⚙
+
+
+
سری OpenClaw
+
معماری، امنیت، و ژئوپلیتیک عاملهای متنباز
+
+
+
+
+ {openclawCluster.map((a) =>
)}
+
+
+ )}
+
+ {/* Security & Legal Cluster */}
+ {securityCluster.length > 0 && (
+
+
+
+ ⚖
+
+
+
امنیت و حقوق AI
+
مسئولیت حقوقی، ایمنی سایبری، و حاکمیت هوش مصنوعی
+
+
+
+
+ {securityCluster.map((a) =>
)}
+
+
+ )}
+
+ {/* Categories */}
+
+ دستهبندیها
+ کشف مطالب بر اساس حوزه تخصصی
+
+ {TeknavData.categories.map((cat) => {
+ const { navigate } = useNav();
+ return (
+
navigate('/category/' + cat.slug)} style={{
+ background: '#fff', border: `1px solid ${cat.color}30`, borderRadius: 10, padding: '20px 16px',
+ cursor: 'pointer', direction: 'rtl', transition: 'all 0.2s',
+ borderRight: `3px solid ${cat.color}`
+ }} onMouseEnter={(e) => e.currentTarget.style.background = cat.color + '08'}
+ onMouseLeave={(e) => e.currentTarget.style.background = '#fff'}>
+
{cat.name}
+
{cat.description}
+
{cat.articleCount} مقاله
+
);
+
+ })}
+
+
+
+ {/* Authors */}
+
+
+ {/* Newsletter */}
+
+
+
+
+
+
✉
+
عضو خبرنامه تکناو شوید
+
هر هفته بهترین مقالههای تحلیلی تکناو مستقیم در صندوق ورودی ایمیل شما
+
+
+
+
+
+
+ );
+
+}
+
+// ── Article Row Compact (for homepage) ─────────────────────────────────────
+function ArticleRowCompact({ article }) {
+ const { navigate } = useNav();
+ const ref = useRef();
+ useViewportPrefetch(ref, article.slug);
+ const cat = TeknavData.categories.find((c) => c.id === article.category);
+ return (
+ navigate('/article/' + article.slug)} style={{
+ display: 'flex', gap: 20, padding: '20px 0', borderBottom: '1px solid #E4DDD2',
+ cursor: 'pointer', direction: 'rtl', alignItems: 'flex-start',
+ transition: 'background 0.15s'
+ }} onMouseEnter={(e) => e.currentTarget.style.background = '#F4EFE620'}
+ onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
+
+
+
+
+
+
{article.title}
+
{article.summary.slice(0, 140)}…
+
{article.authorName} · {article.date} · {article.readTime} دقیقه
+
+
+
);
+
+}
+
+export { HomePage, ArticleCard, FeaturedArticle, ArticleRowCompact, sectionTitle, sectionSubtitle };