Skip to content

Commit 730f7ff

Browse files
committed
feat: add PixelatedCanvas component for interactive pixel art rendering
1 parent 64c663e commit 730f7ff

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+5512
-77
lines changed

CHANGELOG.md

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Atlas Frontend Development Changelog
22

3-
## Current Status: Core System Complete ✅ + TOC Issues 🚧
3+
## Current Status: Production Ready ✅ + Search Implementation Needed 🚧
44

55
### 🎯 What We've Built
66

@@ -90,37 +90,55 @@
9090
- `src/app/api/articles/route.ts` - API endpoint for client components
9191
- `scripts/optimize-thumbnails.sh` - Asset optimization tool
9292

93-
### 🚧 Current Issues (Priority Fix)
93+
### ✅ Recent Fixes Completed (Sept 21)
9494

95-
1. **TOC Visual Separator Issue (Dialogue Pages):**
96-
- Problem: Attempted to move TL;DR separator logic, created complexity
97-
- Current State: Dialogue pages try to split at "TL;DR" but separator not rendering
98-
- Files Affected: `src/app/atlas/dialogue/[slug]/page.tsx` lines 44-47, 151-156
99-
- Simple Fix Needed: Revert separator logic back to "Our Conclusion" split
100-
- TOC highlighting works correctly, just separator placement is broken
95+
1. **TL;DR Separator System:**
96+
- Fixed component to detect `**TL;DR:**` in markdown content
97+
- Works for both monologues and dialogues
98+
- Visual separator renders properly with "TL;DR" label
10199

102-
2. **TOC Highlighting Edge Case:**
103-
- Minor: "Our Conclusion" section highlighting ends early when scrolling past
104-
- Acceptable for now, complex fix needed for proper end-of-content detection
100+
2. **PersonaBadge Optimization:**
101+
- Switched from video to static images for consistency
102+
- Removed unused `videoSrc` prop from interface
103+
- Fixed all TypeScript errors and component calls
105104

106-
### 📋 Next Steps (Priority Order)
105+
3. **Content System:**
106+
- Added Darwin evolution article (ready for publication)
107+
- Added Rachel Carson and Charles Darwin to personas data
108+
- All 3 existing articles properly formatted
107109

108-
1. **Fix TOC Separator:**
109-
- Revert dialogue separator back to "Our Conclusion"
110-
- Keep TOC working as-is (it's functional)
110+
4. **Code Quality:**
111+
- Fixed 28 ESLint issues → 2 warnings
112+
- Fixed 12 TypeScript errors → 0 errors
113+
- Removed unused imports and variables
114+
- Improved type safety throughout
111115

112-
2. **Content Creation:**
113-
- Add more articles using the 27 personas available
114-
- Test dual-author dialogues with PersonaBadge system
116+
5. **About Page Redesign:**
117+
- New founder-centric layout with pixelated canvas
118+
- Clean 2-person team structure
119+
- AgentBuilder concept as page description
115120

116-
3. **Search Functionality:**
121+
### 🚧 Remaining Tasks (Priority Order)
122+
123+
1. **Search Functionality (Primary):**
117124
- Implement search bar in Explore page (currently placeholder)
118-
- Add filtering by author, type, tags
125+
- Add client-side filtering by title, author, type, tags
126+
- Consider fuzzy search or highlighting matches
127+
128+
2. **Content Workflow:**
129+
- Set up inbox folder for new articles
130+
- Test content generation → QA → publication workflow
131+
- Add more articles using the 27 available personas
132+
133+
3. **Frontend Polish:**
134+
- Update metadata in `layout.tsx` (title, description)
135+
- Add disclaimer about AI personas (as discussed)
136+
- Mobile responsiveness final testing
119137

120-
4. **Polish & Performance:**
121-
- Mobile responsiveness testing
122-
- Loading states optimization
123-
- SEO and metadata
138+
4. **Performance & SEO:**
139+
- Optimize image loading
140+
- Add proper meta tags for articles
141+
- Test static generation performance
124142

125143
### 🎨 Design System
126144

@@ -157,14 +175,23 @@
157175
## For Next Developer
158176

159177
**Start Here:**
160-
1. Review this changelog
161-
2. Check `src/app/atlas/page.tsx` - needs Twitter-style conversion
162-
3. Look at `src/app/explore/page.tsx` - example of PersonaBadge integration
163-
4. Test persona video loading and modal interactions
164-
165-
**Quick Wins:**
166-
- Atlas feed conversion (~2-3 hours)
167-
- Search functionality (~3-4 hours)
168-
- Additional content creation (~1-2 hours)
169-
170-
**Codebase Health:** ✅ Clean, typed, well-organized, ready for handoff
178+
1. Review this changelog - system is production-ready
179+
2. Primary task: Search functionality in `src/app/explore/page.tsx`
180+
3. Test all pages: Agency, Atlas, Explore, About work perfectly
181+
4. Content system ready for scaling
182+
183+
**Current State:**
184+
- ✅ All core features complete and working
185+
- ✅ Code quality excellent (0 TS errors, 2 minor warnings)
186+
- ✅ 3 articles published, personas system ready
187+
- ✅ About page redesigned with founder focus
188+
- 🚧 Search bar in Explore page needs implementation
189+
190+
**Quick Implementation Targets:**
191+
- Search functionality (~2-3 hours)
192+
- Metadata updates (~30 minutes)
193+
- Content workflow setup (~1 hour)
194+
195+
**Codebase Health:** ✅ Production-ready, clean architecture, excellent handoff state
196+
197+
**Theme System:** Tailwind CSS v4 + Geist fonts + auto dark/light mode via `globals.css` and `layout.tsx`
20.3 KB
Loading
1.54 MB
Loading

public/images/team/founder.png

179 KB
Loading
758 KB
Binary file not shown.
7.31 MB
Binary file not shown.

src copy/app/about/[slug]/page.tsx

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import { getArticleBySlug, getAllArticles } from '@/lib/markdown'
2+
import { AppSidebar } from '@/components/app-sidebar'
3+
import { TracingBeam } from '@/components/ui/tracing-beam'
4+
import { cn } from '@/lib/utils'
5+
import { notFound } from 'next/navigation'
6+
import Link from 'next/link'
7+
import { ArrowLeft, Clock, Tag, User, Calendar, Share2 } from 'lucide-react'
8+
import { Toc } from '@/components/ui/toc'
9+
10+
interface ArticlePageProps {
11+
params: {
12+
slug: string
13+
}
14+
}
15+
16+
export async function generateStaticParams() {
17+
const articles = await getAllArticles()
18+
return articles.map((article) => ({
19+
slug: article.slug,
20+
}))
21+
}
22+
23+
// TOC moved to client component '@/components/ui/toc'
24+
25+
export default async function ArticlePage({ params }: ArticlePageProps) {
26+
const article = await getArticleBySlug(params.slug)
27+
28+
if (!article) {
29+
notFound()
30+
}
31+
32+
const readingTime = Math.ceil(article.content.replace(/<[^>]*>/g, '').split(' ').length / 200)
33+
// Remove only the inline "Continue the Exploration..." section (keep trailing keywords/source)
34+
const withoutInlineContinue = article.content.replace(
35+
/<h[2-3][^>]*>\s*Continue the Exploration\.\.\.\s*<\/h[2-3]>[\s\S]*?(?=<hr\b|<h[1-6]|$)/i,
36+
'',
37+
)
38+
// Split after the opening paragraph/question: find first section heading (h2/h3)
39+
const firstSection = /<h[2-3][^>]*>/i.exec(withoutInlineContinue)
40+
const introHtml = firstSection ? withoutInlineContinue.slice(0, firstSection.index) : ''
41+
const contentAfterIntro = firstSection ? withoutInlineContinue.slice(firstSection.index) : withoutInlineContinue
42+
43+
return (
44+
<div className={cn("flex flex-col md:flex-row bg-gray-100 dark:bg-neutral-800 w-full flex-1 mx-auto border border-neutral-200 dark:border-neutral-700 overflow-visible md:overflow-hidden min-h-screen md:h-screen")}>
45+
<AppSidebar />
46+
<div className="flex flex-1">
47+
<div id="scroll-container" className="p-2 md:p-10 rounded-tl-2xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 flex flex-col gap-2 flex-1 w-full md:h-full h-auto md:overflow-y-auto overflow-visible">
48+
<div className="flex gap-8 max-w-7xl mx-auto w-full">
49+
{/* Main Content */}
50+
<div className="flex-1 min-w-0">
51+
<TracingBeam className="px-6">
52+
<div className="max-w-2xl mx-auto antialiased pt-4 relative">
53+
{/* Back Button */}
54+
<Link
55+
href="/atlas"
56+
className="inline-flex items-center gap-2 text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-100 mb-8 group"
57+
>
58+
<ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform" />
59+
Back to Atlas
60+
</Link>
61+
62+
{/* Article Header */}
63+
<header className="mb-12">
64+
65+
<h1 className="text-4xl md:text-5xl font-bold text-neutral-900 dark:text-neutral-100 mb-6 leading-tight">
66+
{article.frontmatter.title}
67+
</h1>
68+
69+
{article.frontmatter.summary && (
70+
<p className="text-xl text-neutral-700 dark:text-neutral-300 leading-relaxed mb-8 font-medium">
71+
{article.frontmatter.summary}
72+
</p>
73+
)}
74+
75+
{/* Meta Information */}
76+
<div className="flex flex-wrap items-center gap-6 text-sm text-neutral-600 dark:text-neutral-400 mb-8">
77+
{article.frontmatter.author && (
78+
<div className="flex items-center gap-2">
79+
<User className="w-4 h-4" />
80+
<span>{article.frontmatter.author}</span>
81+
</div>
82+
)}
83+
84+
<div className="flex items-center gap-2">
85+
<Calendar className="w-4 h-4" />
86+
<time dateTime={article.frontmatter.date}>
87+
{new Date(article.frontmatter.date).toLocaleDateString('en-US', {
88+
year: 'numeric',
89+
month: 'long',
90+
day: 'numeric'
91+
})}
92+
</time>
93+
</div>
94+
95+
<div className="flex items-center gap-2">
96+
<Clock className="w-4 h-4" />
97+
<span>{readingTime} min read</span>
98+
</div>
99+
100+
<button className="flex items-center gap-2 hover:text-neutral-900 dark:hover:text-neutral-100 transition-colors">
101+
<Share2 className="w-4 h-4" />
102+
<span>Share</span>
103+
</button>
104+
</div>
105+
106+
{/* Tags */}
107+
{article.frontmatter.tags && article.frontmatter.tags.length > 0 && (
108+
<div className="flex flex-wrap gap-2 mb-8">
109+
{article.frontmatter.tags.map((tag) => (
110+
<span
111+
key={tag}
112+
className="inline-flex items-center gap-1 px-3 py-1 bg-neutral-100 dark:bg-neutral-800 text-neutral-700 dark:text-neutral-300 rounded-full text-sm"
113+
>
114+
<Tag className="w-3 h-3" />
115+
{tag}
116+
</span>
117+
))}
118+
</div>
119+
)}
120+
</header>
121+
122+
{/* Monologue Content */}
123+
{/* Intro paragraph/question */}
124+
{introHtml && (
125+
<article
126+
className="prose prose-neutral dark:prose-invert prose-lg max-w-prose prose-p:leading-relaxed prose-p:text-neutral-700 dark:prose-p:text-neutral-300"
127+
dangerouslySetInnerHTML={{ __html: introHtml }}
128+
/>
129+
)}
130+
131+
{/* Decorative separator under the intro */}
132+
{introHtml && (
133+
<div className="my-8 flex items-center">
134+
<div className="h-px flex-1 bg-gradient-to-r from-transparent via-blue-300 to-transparent dark:via-blue-700" />
135+
<span className="mx-3 text-xs uppercase tracking-wide text-neutral-500 dark:text-neutral-400">Deep Dive</span>
136+
<div className="h-px flex-1 bg-gradient-to-r from-transparent via-purple-300 to-transparent dark:via-purple-700" />
137+
</div>
138+
)}
139+
140+
{/* Main content */}
141+
<article id="article-root"
142+
className="prose prose-neutral dark:prose-invert prose-lg max-w-prose prose-headings:scroll-mt-8 prose-headings:font-bold prose-h1:text-3xl prose-h1:mb-8 prose-h2:text-2xl prose-h2:mt-12 prose-h2:mb-6 prose-h3:text-xl prose-h3:mt-8 prose-h3:mb-4 prose-p:leading-relaxed prose-p:text-neutral-700 dark:prose-p:text-neutral-300 prose-blockquote:border-l-4 prose-blockquote:border-blue-500 prose-blockquote:bg-blue-50 dark:prose-blockquote:bg-blue-950/30 prose-blockquote:py-2 prose-blockquote:px-4 prose-strong:text-neutral-900 dark:prose-strong:text-neutral-100 prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-a:no-underline hover:prose-a:underline"
143+
dangerouslySetInnerHTML={{ __html: contentAfterIntro }}
144+
/>
145+
146+
{/* Continue Exploration Section (bottom card) */}
147+
<div className="mt-16 p-6 bg-gradient-to-r from-blue-50 to-purple-50 dark:from-blue-950/30 dark:to-purple-950/30 rounded-xl border border-blue-200 dark:border-blue-800">
148+
<h3 className="text-lg font-semibold text-neutral-900 dark:text-neutral-100 mb-4">
149+
Continue the Exploration...
150+
</h3>
151+
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
152+
<Link href="#" className="p-3 bg-white dark:bg-neutral-800 rounded-lg border border-neutral-200 dark:border-neutral-700 hover:border-blue-300 dark:hover:border-blue-600 transition-colors">
153+
<span className="text-sm font-medium text-neutral-900 dark:text-neutral-100">Collaborative Reality Mathematics</span>
154+
</Link>
155+
<Link href="#" className="p-3 bg-white dark:bg-neutral-800 rounded-lg border border-neutral-200 dark:border-neutral-700 hover:border-blue-300 dark:hover:border-blue-600 transition-colors">
156+
<span className="text-sm font-medium text-neutral-900 dark:text-neutral-100">Identity Fractals at the Mortality Boundary</span>
157+
</Link>
158+
</div>
159+
</div>
160+
161+
{/* Source Information */}
162+
{article.frontmatter.source_run_id && (
163+
<div className="mt-8 pt-8 border-t border-neutral-200 dark:border-neutral-700">
164+
<div className="text-xs text-neutral-500 dark:text-neutral-500">
165+
<strong>Keywords:</strong> {article.frontmatter.tags?.join(', ')}
166+
{article.frontmatter.source_files && (
167+
<div className="mt-1">
168+
<strong>Source:</strong> Adapted from Trinity dialogue series, Run {article.frontmatter.source_run_id}
169+
</div>
170+
)}
171+
</div>
172+
</div>
173+
)}
174+
</div>
175+
</TracingBeam>
176+
</div>
177+
178+
{/* Right Sidebar - TOC with highlight & LLM Export */}
179+
<div className="hidden xl:block">
180+
<Toc contentHtml={contentAfterIntro} />
181+
</div>
182+
</div>
183+
</div>
184+
</div>
185+
</div>
186+
)
187+
}

src copy/app/about/page.tsx

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { AppSidebar } from '@/components/app-sidebar'
2+
import { cn } from '@/lib/utils'
3+
import { PixelatedCanvas } from '@/components/ui/pixelated-canvas'
4+
5+
const teamMembers = [
6+
{
7+
name: "Founder",
8+
role: "The Architect",
9+
description: "Provides the creative vision, asks the foundational \"Why,\" and guides the symbiotic partnership that breathes life into the system.",
10+
image: "/images/team/founder.png"
11+
},
12+
{
13+
name: "Ruixen",
14+
role: "The Facilitator",
15+
description: "A symbiotic AI partner that structures knowledge, executes complex tasks, and transforms vision into tangible reality.",
16+
image: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?q=80&w=3387&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
17+
}
18+
]
19+
20+
export default function AboutPage() {
21+
return (
22+
<div className={cn("flex flex-col md:flex-row bg-gray-100 dark:bg-neutral-800 w-full flex-1 mx-auto border border-neutral-200 dark:border-neutral-700 overflow-hidden h-screen")}>
23+
<AppSidebar />
24+
<div className="flex flex-1">
25+
<div className="p-2 md:p-10 rounded-tl-2xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 flex flex-col gap-2 flex-1 w-full h-full overflow-y-auto">
26+
<div className="max-w-6xl mx-auto w-full py-8">
27+
28+
{/* Header Section */}
29+
<div className="text-center mb-16">
30+
<h1 className="text-4xl md:text-5xl font-bold text-neutral-900 dark:text-neutral-100 mb-6">
31+
About Ruixen
32+
</h1>
33+
<p className="text-xl text-neutral-600 dark:text-neutral-400 max-w-3xl mx-auto leading-relaxed">
34+
A living ecosystem of tools, playbooks, and knowledge generated from human-AI collaboration.
35+
The engine of creation and platform for future discovery.
36+
</p>
37+
</div>
38+
39+
{/* Team Cards */}
40+
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-16 max-w-5xl mx-auto">
41+
{teamMembers.map((member, index) => (
42+
<div key={index} className="group">
43+
{/* Pixelated Canvas Avatar */}
44+
<div className="relative mb-6 mx-auto w-64 h-64 md:w-80 md:h-80">
45+
<div className="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-purple-500/20 rounded-2xl transform group-hover:scale-105 transition-transform duration-300" />
46+
<div className="relative rounded-2xl overflow-hidden border-2 border-neutral-200 dark:border-neutral-700 group-hover:border-blue-500/50 transition-colors duration-300">
47+
<PixelatedCanvas
48+
src={member.image}
49+
width={320}
50+
height={320}
51+
interactive={true}
52+
className="w-full h-full"
53+
/>
54+
</div>
55+
</div>
56+
57+
{/* Content */}
58+
<div className="text-center space-y-4">
59+
<div>
60+
<h3 className="text-2xl font-bold text-neutral-900 dark:text-neutral-100 mb-2">
61+
{member.name}
62+
</h3>
63+
<p className="text-lg text-blue-600 dark:text-blue-400 font-medium">
64+
{member.role}
65+
</p>
66+
</div>
67+
68+
<p className="text-neutral-600 dark:text-neutral-400 leading-relaxed max-w-sm mx-auto">
69+
{member.description}
70+
</p>
71+
</div>
72+
</div>
73+
))}
74+
</div>
75+
76+
</div>
77+
</div>
78+
</div>
79+
</div>
80+
)
81+
}

0 commit comments

Comments
 (0)