Skip to content

Commit 7d8cc75

Browse files
committed
feat: update README with project description and features; refactor font usage and add InfiniteMovingCards component for dynamic quote display
1 parent 730f7ff commit 7d8cc75

File tree

6 files changed

+216
-38
lines changed

6 files changed

+216
-38
lines changed

README.md

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,29 @@
1-
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
1+
# Atlas
22

3-
## Getting Started
3+
> Where history's greatest minds meet tomorrow's intelligence
44
5-
First, run the development server:
5+
Atlas is a curated platform for exploring conversations between history's most influential thinkers and the cutting edge of artificial intelligence. Through carefully crafted dialogues and monologues, we bridge centuries of human wisdom with modern computational thinking.
66

7-
```bash
8-
npm run dev
9-
# or
10-
yarn dev
11-
# or
12-
pnpm dev
13-
# or
14-
bun dev
15-
```
7+
## What Atlas Offers
168

17-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
9+
**🏛️ Agency** - Meet 27 historical personas, from Nobel laureates to classical philosophers. Each figure comes to life through rich biographical content and authentic voice modeling.
1810

19-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
11+
**📚 Atlas Feed** - Discover thought-provoking articles in an elegant, reader-focused interface. Each piece explores deep questions through the lens of great minds.
2012

21-
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
13+
**🔍 Explore** - Search and filter through our growing collection of dialogues, monologues, and analytical pieces. Find exactly what sparks your curiosity.
2214

23-
## Learn More
15+
**💭 Dialogues** - Witness conversations that transcend time. Watch Darwin and Turing explore the computational nature of evolution, or see Ostrom and Wiener debate cybernetic governance.
2416

25-
To learn more about Next.js, take a look at the following resources:
17+
**📝 Monologues** - Experience the world through the eyes of history's greatest thinkers. From Feynman on consciousness to Turing on machine intelligence.
2618

27-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
19+
## Featured Thinkers
2920

30-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
21+
Our current collection includes minds like Richard Feynman, Marie Curie, Alan Turing, Charles Darwin, Elinor Ostrom, Marcus Aurelius, Hannah Arendt, Leonardo da Vinci, and many others - each contributing their unique perspective to modern questions.
3122

32-
## Deploy on Vercel
23+
## Philosophy
3324

34-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
25+
Atlas believes that the wisdom of the past can illuminate the challenges of tomorrow. By creating authentic conversations between historical figures and contemporary ideas, we explore how timeless insights apply to our rapidly evolving world.
3526

36-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
27+
---
28+
29+
*Built with Next.js, TypeScript, and Tailwind CSS. Powered by thoughtful design and respect for intellectual heritage.*

src/app/about/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ export default function AboutPage() {
3939
{/* Team Cards */}
4040
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-16 max-w-5xl mx-auto">
4141
{teamMembers.map((member, index) => (
42-
<div key={index} className="group">
42+
<div key={index}>
4343
{/* Pixelated Canvas Avatar */}
4444
<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">
45+
<div className="absolute inset-0 bg-gradient-to-br from-blue-500/20 to-purple-500/20 rounded-2xl" />
46+
<div className="relative rounded-2xl overflow-hidden border-2 border-neutral-200 dark:border-neutral-700">
4747
<PixelatedCanvas
4848
src={member.image}
4949
width={320}

src/app/globals.css

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
@theme inline {
1010
--color-background: var(--background);
1111
--color-foreground: var(--foreground);
12-
--font-sans: var(--font-geist-sans);
13-
--font-mono: var(--font-geist-mono);
12+
--font-sans: var(--font-chakra-petch);
13+
--font-mono: var(--font-chakra-petch);
1414
}
1515

1616
@media (prefers-color-scheme: dark) {
@@ -23,5 +23,15 @@
2323
body {
2424
background: var(--background);
2525
color: var(--foreground);
26-
font-family: Arial, Helvetica, sans-serif;
26+
font-family: var(--font-chakra-petch), Arial, Helvetica, sans-serif;
27+
}
28+
29+
@keyframes scroll {
30+
to {
31+
transform: translate(calc(-50% - 0.5rem));
32+
}
33+
}
34+
35+
.animate-scroll {
36+
animation: scroll var(--animation-duration, 40s) var(--animation-direction, forwards) linear infinite;
2737
}

src/app/layout.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import type { Metadata } from "next";
2-
import { Geist, Geist_Mono } from "next/font/google";
2+
import { Chakra_Petch } from "next/font/google";
33
import "./globals.css";
44

5-
const geistSans = Geist({
6-
variable: "--font-geist-sans",
7-
subsets: ["latin"],
8-
});
9-
10-
const geistMono = Geist_Mono({
11-
variable: "--font-geist-mono",
5+
const chakraPetch = Chakra_Petch({
6+
variable: "--font-chakra-petch",
127
subsets: ["latin"],
8+
weight: ["300", "400", "500", "600", "700"],
139
});
1410

1511
export const metadata: Metadata = {
@@ -25,7 +21,7 @@ export default function RootLayout({
2521
return (
2622
<html lang="en">
2723
<body
28-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
24+
className={`${chakraPetch.variable} antialiased`}
2925
>
3026
{children}
3127
</body>

src/app/page.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,67 @@
11
import { AppSidebar } from '@/components/app-sidebar'
22
import { BackgroundBeams } from '@/components/ui/background-beams'
3+
import { InfiniteMovingCards } from '@/components/ui/infinite-moving-cards'
34
import { cn } from '@/lib/utils'
5+
import { personas } from '@/data/personas'
6+
7+
// Extract quotes from personas data
8+
function getQuotesFromPersonas() {
9+
const quotes: { quote: string; name: string; title: string }[] = []
10+
11+
personas.forEach(persona => {
12+
if (persona.famousQuotes && persona.famousQuotes.length > 0) {
13+
// Get 1-2 best quotes per persona to avoid overwhelming
14+
const quotesToUse = persona.famousQuotes.slice(0, 2)
15+
quotesToUse.forEach(quote => {
16+
quotes.push({
17+
quote,
18+
name: persona.name,
19+
title: persona.title
20+
})
21+
})
22+
}
23+
})
24+
25+
// Shuffle quotes for variety
26+
return quotes.sort(() => Math.random() - 0.5)
27+
}
428

529
export default function Home() {
30+
const quotes = getQuotesFromPersonas()
31+
632
return (
733
<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")}>
834
<AppSidebar />
935
<div className="flex flex-1">
1036
<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 relative">
1137
<BackgroundBeams />
38+
39+
{/* Hero Content */}
40+
<div className="relative z-20 flex flex-col items-center justify-center h-full">
41+
<div className="text-center mb-16">
42+
<h1 className="text-4xl md:text-6xl font-bold text-neutral-900 dark:text-neutral-100 mb-6">
43+
Atlas
44+
</h1>
45+
<p className="text-xl md:text-2xl text-neutral-600 dark:text-neutral-400 max-w-3xl mx-auto">
46+
Where history's greatest minds meet tomorrow's intelligence
47+
</p>
48+
</div>
49+
50+
{/* Flying Quotes */}
51+
<div className="w-full">
52+
<InfiniteMovingCards
53+
items={quotes}
54+
direction="right"
55+
speed="slow"
56+
className="mb-8"
57+
/>
58+
<InfiniteMovingCards
59+
items={quotes.slice().reverse()}
60+
direction="left"
61+
speed="normal"
62+
/>
63+
</div>
64+
</div>
1265
</div>
1366
</div>
1467
</div>
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"use client";
2+
3+
import { cn } from "@/lib/utils";
4+
import React, { useEffect, useState } from "react";
5+
6+
export const InfiniteMovingCards = ({
7+
items,
8+
direction = "left",
9+
speed = "fast",
10+
pauseOnHover = true,
11+
className,
12+
}: {
13+
items: {
14+
quote: string;
15+
name: string;
16+
title: string;
17+
}[];
18+
direction?: "left" | "right";
19+
speed?: "fast" | "normal" | "slow";
20+
pauseOnHover?: boolean;
21+
className?: string;
22+
}) => {
23+
const containerRef = React.useRef<HTMLDivElement>(null);
24+
const scrollerRef = React.useRef<HTMLUListElement>(null);
25+
26+
useEffect(() => {
27+
addAnimation();
28+
}, []);
29+
30+
const [start, setStart] = useState(false);
31+
32+
function addAnimation() {
33+
if (containerRef.current && scrollerRef.current) {
34+
const scrollerContent = Array.from(scrollerRef.current.children);
35+
36+
scrollerContent.forEach((item) => {
37+
const duplicatedItem = item.cloneNode(true);
38+
if (scrollerRef.current) {
39+
scrollerRef.current.appendChild(duplicatedItem);
40+
}
41+
});
42+
43+
getDirection();
44+
getSpeed();
45+
setStart(true);
46+
}
47+
}
48+
49+
const getDirection = () => {
50+
if (containerRef.current) {
51+
if (direction === "left") {
52+
containerRef.current.style.setProperty(
53+
"--animation-direction",
54+
"forwards"
55+
);
56+
} else {
57+
containerRef.current.style.setProperty(
58+
"--animation-direction",
59+
"reverse"
60+
);
61+
}
62+
}
63+
};
64+
65+
const getSpeed = () => {
66+
if (containerRef.current) {
67+
if (speed === "fast") {
68+
containerRef.current.style.setProperty("--animation-duration", "20s");
69+
} else if (speed === "normal") {
70+
containerRef.current.style.setProperty("--animation-duration", "40s");
71+
} else {
72+
containerRef.current.style.setProperty("--animation-duration", "80s");
73+
}
74+
}
75+
};
76+
77+
return (
78+
<div
79+
ref={containerRef}
80+
className={cn(
81+
"scroller relative z-20 max-w-7xl overflow-hidden [mask-image:linear-gradient(to_right,transparent,white_20%,white_80%,transparent)]",
82+
className
83+
)}
84+
>
85+
<ul
86+
ref={scrollerRef}
87+
className={cn(
88+
"flex min-w-full shrink-0 gap-4 py-4 w-max flex-nowrap",
89+
start && "animate-scroll",
90+
pauseOnHover && "hover:[animation-play-state:paused]"
91+
)}
92+
>
93+
{items.map((item, idx) => (
94+
<li
95+
className="w-[350px] max-w-full relative rounded-2xl border border-b-0 flex-shrink-0 border-slate-700 px-8 py-6 md:w-[450px]"
96+
style={{
97+
background:
98+
"linear-gradient(180deg, var(--slate-800), var(--slate-900))",
99+
}}
100+
key={idx}
101+
>
102+
<blockquote>
103+
<div
104+
aria-hidden="true"
105+
className="user-select-none -z-1 pointer-events-none absolute -left-0.5 -top-0.5 h-[calc(100%_+_4px)] w-[calc(100%_+_4px)]"
106+
></div>
107+
<span className="relative z-20 text-sm leading-[1.6] text-gray-100 font-normal">
108+
"{item.quote}"
109+
</span>
110+
<div className="relative z-20 mt-6 flex flex-row items-center">
111+
<span className="flex flex-col gap-1">
112+
<span className="text-sm leading-[1.6] text-gray-400 font-normal">
113+
{item.name}
114+
</span>
115+
<span className="text-sm leading-[1.6] text-gray-400 font-normal">
116+
{item.title}
117+
</span>
118+
</span>
119+
</div>
120+
</blockquote>
121+
</li>
122+
))}
123+
</ul>
124+
</div>
125+
);
126+
};

0 commit comments

Comments
 (0)