my blog https://overreacted.io
1import Link from "./Link";
2import Color from "colorjs.io";
3import { metadata, getPosts, Post } from "./posts";
4import { sans } from "./fonts";
5
6export { metadata };
7
8export default async function Home() {
9 const posts = await getPosts();
10 return (
11 <div className="relative -top-[10px] flex flex-col gap-8">
12 {posts.map((post) => (
13 <Link
14 key={post.slug}
15 className="block py-4 hover:scale-[1.005] will-change-transform"
16 href={"/" + post.slug + "/"}
17 >
18 <article>
19 <PostTitle post={post} />
20 <PostMeta post={post} />
21 <PostSubtitle post={post} />
22 </article>
23 </Link>
24 ))}
25 </div>
26 );
27}
28
29function PostTitle({ post }: { post: Post }) {
30 let lightStart = new Color("lab(63 59.32 -1.47)");
31 let lightEnd = new Color("lab(33 42.09 -43.19)");
32 let lightRange = lightStart.range(lightEnd);
33 let darkStart = new Color("lab(81 32.36 -7.02)");
34 let darkEnd = new Color("lab(78 19.97 -36.75)");
35 let darkRange = darkStart.range(darkEnd);
36 let today = new Date();
37 let timeSinceFirstPost = (today.getTime() - new Date(2018, 10, 30).getTime());
38 let timeSinceThisPost = (today.getTime() - new Date(post.date).getTime());
39 let staleness = timeSinceThisPost / timeSinceFirstPost;
40
41 return (
42 <h2
43 className={[
44 sans.className,
45 "text-[28px] font-black leading-none mb-2",
46 "text-[--lightLink] dark:text-[--darkLink]",
47 ].join(" ")}
48 style={{
49 "--lightLink": lightRange(staleness).toString(),
50 "--darkLink": darkRange(staleness).toString(),
51 } as any}
52 >
53 {post.title}
54 </h2>
55 );
56}
57
58function PostMeta({ post }: { post: Post }) {
59 return (
60 <p className="text-[13px] text-gray-700 dark:text-gray-300">
61 {new Date(post.date).toLocaleDateString("en", {
62 day: "numeric",
63 month: "long",
64 year: "numeric",
65 })}
66 </p>
67 );
68}
69
70function PostSubtitle({ post }: { post: Post }) {
71 return <p className="mt-1">{post.spoiler}</p>;
72}