Skip to content

Commit de831c8

Browse files
committed
improvement: blog
1 parent 9be1202 commit de831c8

File tree

5 files changed

+205
-173
lines changed

5 files changed

+205
-173
lines changed
Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,55 @@
11
import { Skeleton } from '@/components/emcn'
22

3-
const SKELETON_CARD_COUNT = 6
4-
53
export default function BlogLoading() {
64
return (
7-
<main className='mx-auto max-w-[1200px] px-6 py-12 sm:px-8 md:px-12'>
8-
<Skeleton className='h-[48px] w-[100px] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
9-
<Skeleton className='mt-3 h-[18px] w-[420px] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
10-
<div className='mt-10 grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6 lg:grid-cols-3'>
11-
{Array.from({ length: SKELETON_CARD_COUNT }).map((_, i) => (
12-
<div
13-
key={i}
14-
className='flex flex-col overflow-hidden rounded-xl border border-[var(--landing-border)]'
15-
>
16-
<Skeleton className='aspect-video w-full rounded-none bg-[var(--landing-bg-elevated)]' />
17-
<div className='flex flex-1 flex-col p-4'>
18-
<Skeleton className='mb-2 h-[12px] w-[80px] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
19-
<Skeleton className='mb-1 h-[20px] w-[85%] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
20-
<Skeleton className='mb-3 h-[14px] w-full rounded-[4px] bg-[var(--landing-bg-elevated)]' />
21-
<Skeleton className='h-[14px] w-[70%] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
22-
<div className='mt-3 flex items-center gap-2'>
23-
<Skeleton className='h-[16px] w-[16px] rounded-full bg-[var(--landing-bg-elevated)]' />
24-
<Skeleton className='h-[12px] w-[80px] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
5+
<section className='bg-[var(--landing-bg)]'>
6+
{/* Header skeleton */}
7+
<div className='px-5 pt-[60px] lg:px-16 lg:pt-[100px]'>
8+
<Skeleton className='mb-5 h-[20px] w-[60px] rounded-md bg-[var(--landing-bg-elevated)]' />
9+
<div className='flex flex-col gap-4 md:flex-row md:items-end md:justify-between'>
10+
<Skeleton className='h-[40px] w-[240px] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
11+
<Skeleton className='h-[18px] w-[320px] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
12+
</div>
13+
</div>
14+
15+
{/* Content area with vertical border rails */}
16+
<div className='mx-5 mt-8 border-[var(--landing-bg-elevated)] border-x lg:mx-16'>
17+
<div className='h-px w-full bg-[var(--landing-bg-elevated)]' />
18+
19+
{/* Featured skeleton */}
20+
<div className='flex'>
21+
{Array.from({ length: 3 }).map((_, i) => (
22+
<div
23+
key={i}
24+
className='flex flex-1 flex-col gap-4 border-[var(--landing-bg-elevated)] p-6 md:border-l md:first:border-l-0'
25+
>
26+
<Skeleton className='aspect-video w-full rounded-[5px] bg-[var(--landing-bg-elevated)]' />
27+
<div className='flex flex-col gap-2'>
28+
<Skeleton className='h-[12px] w-[60px] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
29+
<Skeleton className='h-[20px] w-[80%] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
30+
<Skeleton className='h-[14px] w-full rounded-[4px] bg-[var(--landing-bg-elevated)]' />
31+
</div>
32+
</div>
33+
))}
34+
</div>
35+
36+
<div className='h-px w-full bg-[var(--landing-bg-elevated)]' />
37+
38+
{/* List skeleton */}
39+
{Array.from({ length: 5 }).map((_, i) => (
40+
<div key={i}>
41+
<div className='flex items-center gap-6 px-6 py-6'>
42+
<Skeleton className='hidden h-[14px] w-[120px] rounded-[4px] bg-[var(--landing-bg-elevated)] md:block' />
43+
<div className='flex min-w-0 flex-1 flex-col gap-1'>
44+
<Skeleton className='h-[18px] w-[70%] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
45+
<Skeleton className='h-[14px] w-[90%] rounded-[4px] bg-[var(--landing-bg-elevated)]' />
2546
</div>
47+
<Skeleton className='hidden h-[80px] w-[140px] rounded-[5px] bg-[var(--landing-bg-elevated)] sm:block' />
2648
</div>
49+
<div className='h-px w-full bg-[var(--landing-bg-elevated)]' />
2750
</div>
2851
))}
2952
</div>
30-
</main>
53+
</section>
3154
)
3255
}
Lines changed: 144 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Metadata } from 'next'
22
import Link from 'next/link'
3+
import { Badge } from '@/components/emcn'
34
import { getAllPostMeta } from '@/lib/blog/registry'
4-
import { PostGrid } from '@/app/(landing)/blog/post-grid'
55

66
export const metadata: Metadata = {
77
title: 'Blog',
@@ -34,8 +34,9 @@ export default async function BlogIndex({
3434
const totalPages = Math.max(1, Math.ceil(sorted.length / perPage))
3535
const start = (pageNum - 1) * perPage
3636
const posts = sorted.slice(start, start + perPage)
37-
// Tag filter chips are intentionally disabled for now.
38-
// const tags = await getAllTags()
37+
const featured = pageNum === 1 ? posts.slice(0, 3) : []
38+
const remaining = pageNum === 1 ? posts.slice(3) : posts
39+
3940
const blogJsonLd = {
4041
'@context': 'https://schema.org',
4142
'@type': 'Blog',
@@ -45,54 +46,154 @@ export default async function BlogIndex({
4546
}
4647

4748
return (
48-
<main className='mx-auto max-w-[1200px] px-6 py-12 sm:px-8 md:px-12'>
49+
<section className='bg-[var(--landing-bg)]'>
4950
<script
5051
type='application/ld+json'
5152
dangerouslySetInnerHTML={{ __html: JSON.stringify(blogJsonLd) }}
5253
/>
53-
<h1 className='mb-3 text-balance font-[500] text-[40px] text-[var(--landing-text)] leading-tight sm:text-[56px]'>
54-
Blog
55-
</h1>
56-
<p className='mb-10 text-[var(--landing-text-muted)] text-lg'>
57-
Announcements, insights, and guides for building AI agent workflows.
58-
</p>
59-
60-
{/* Tag filter chips hidden until we have more posts */}
61-
{/* <div className='mb-10 flex flex-wrap gap-3'>
62-
<Link href='/blog' className={`rounded-full border px-3 py-1 text-sm ${!tag ? 'border-black bg-black text-white' : 'border-gray-300'}`}>All</Link>
63-
{tags.map((t) => (
64-
<Link key={t.tag} href={`/blog?tag=${encodeURIComponent(t.tag)}`} className={`rounded-full border px-3 py-1 text-sm ${tag === t.tag ? 'border-black bg-black text-white' : 'border-gray-300'}`}>
65-
{t.tag} ({t.count})
66-
</Link>
67-
))}
68-
</div> */}
6954

70-
{/* Grid layout for consistent rows */}
71-
<PostGrid posts={posts} />
55+
{/* Section header */}
56+
<div className='px-5 pt-[60px] lg:px-16 lg:pt-[100px]'>
57+
<Badge
58+
variant='blue'
59+
size='md'
60+
dot
61+
className='mb-5 bg-white/10 font-season text-white uppercase tracking-[0.02em]'
62+
>
63+
Blog
64+
</Badge>
7265

73-
{totalPages > 1 && (
74-
<div className='mt-10 flex items-center justify-center gap-3'>
75-
{pageNum > 1 && (
76-
<Link
77-
href={`/blog?page=${pageNum - 1}${tag ? `&tag=${encodeURIComponent(tag)}` : ''}`}
78-
className='rounded-[5px] border border-[var(--landing-border-strong)] px-3 py-1 text-[var(--landing-text)] text-sm transition-colors hover:bg-[var(--landing-bg-elevated)]'
79-
>
80-
Previous
81-
</Link>
82-
)}
83-
<span className='text-[var(--landing-text-muted)] text-sm'>
84-
Page {pageNum} of {totalPages}
85-
</span>
86-
{pageNum < totalPages && (
66+
<div className='flex flex-col gap-4 md:flex-row md:items-end md:justify-between'>
67+
<h1 className='text-balance font-[430] font-season text-[28px] text-white leading-[100%] tracking-[-0.02em] lg:text-[40px]'>
68+
Latest from Sim
69+
</h1>
70+
<p className='max-w-[360px] font-[430] font-season text-[#F6F6F0]/50 text-sm leading-[150%] tracking-[0.02em] lg:text-base'>
71+
Announcements, insights, and guides for building AI agent workflows.
72+
</p>
73+
</div>
74+
</div>
75+
76+
{/* Full-width top line */}
77+
<div className='mt-8 h-px w-full bg-[var(--landing-bg-elevated)]' />
78+
79+
{/* Content area with vertical border rails */}
80+
<div className='mx-5 border-[var(--landing-bg-elevated)] border-x lg:mx-16'>
81+
{/* Featured posts */}
82+
{featured.length > 0 && (
83+
<>
84+
<div className='flex'>
85+
{featured.map((p, index) => (
86+
<Link
87+
key={p.slug}
88+
href={`/blog/${p.slug}`}
89+
className='group flex flex-1 flex-col gap-4 border-[var(--landing-bg-elevated)] p-6 transition-colors hover:bg-[var(--landing-bg-elevated)] md:border-l md:first:border-l-0'
90+
>
91+
<div className='relative aspect-video w-full overflow-hidden rounded-[5px]'>
92+
<img
93+
src={p.ogImage}
94+
alt={p.title}
95+
className='h-full w-full object-cover'
96+
loading={index < 3 ? 'eager' : 'lazy'}
97+
/>
98+
</div>
99+
<div className='flex flex-col gap-2'>
100+
<span className='font-martian-mono text-[var(--landing-text-subtle)] text-xs uppercase tracking-[0.1em]'>
101+
{new Date(p.date).toLocaleDateString('en-US', {
102+
month: 'short',
103+
year: '2-digit',
104+
})}
105+
</span>
106+
<h3 className='font-[430] font-season text-lg text-white leading-tight tracking-[-0.01em]'>
107+
{p.title}
108+
</h3>
109+
<p className='line-clamp-2 text-[#F6F6F0]/50 text-sm leading-[150%]'>
110+
{p.description}
111+
</p>
112+
</div>
113+
</Link>
114+
))}
115+
</div>
116+
117+
<div className='h-px w-full bg-[var(--landing-bg-elevated)]' />
118+
</>
119+
)}
120+
121+
{remaining.map((p) => (
122+
<div key={p.slug}>
87123
<Link
88-
href={`/blog?page=${pageNum + 1}${tag ? `&tag=${encodeURIComponent(tag)}` : ''}`}
89-
className='rounded-[5px] border border-[var(--landing-border-strong)] px-3 py-1 text-[var(--landing-text)] text-sm transition-colors hover:bg-[var(--landing-bg-elevated)]'
124+
href={`/blog/${p.slug}`}
125+
className='group flex items-start gap-6 px-6 py-6 transition-colors hover:bg-[var(--landing-bg-elevated)] md:items-center'
90126
>
91-
Next
127+
{/* Date */}
128+
<span className='hidden w-[120px] shrink-0 pt-1 font-martian-mono text-[var(--landing-text-subtle)] text-xs uppercase tracking-[0.1em] md:block'>
129+
{new Date(p.date).toLocaleDateString('en-US', {
130+
month: 'short',
131+
day: 'numeric',
132+
year: 'numeric',
133+
})}
134+
</span>
135+
136+
{/* Title + description */}
137+
<div className='flex min-w-0 flex-1 flex-col gap-1'>
138+
<span className='font-martian-mono text-[var(--landing-text-subtle)] text-xs uppercase tracking-[0.1em] md:hidden'>
139+
{new Date(p.date).toLocaleDateString('en-US', {
140+
month: 'short',
141+
day: 'numeric',
142+
year: 'numeric',
143+
})}
144+
</span>
145+
<h3 className='font-[430] font-season text-base text-white leading-tight tracking-[-0.01em] lg:text-lg'>
146+
{p.title}
147+
</h3>
148+
<p className='line-clamp-2 text-[#F6F6F0]/40 text-sm leading-[150%]'>
149+
{p.description}
150+
</p>
151+
</div>
152+
153+
{/* Image */}
154+
<div className='hidden h-[80px] w-[140px] shrink-0 overflow-hidden rounded-[5px] sm:block'>
155+
<img
156+
src={p.ogImage}
157+
alt={p.title}
158+
className='h-full w-full object-cover'
159+
loading='lazy'
160+
/>
161+
</div>
92162
</Link>
93-
)}
94-
</div>
95-
)}
96-
</main>
163+
<div className='h-px w-full bg-[var(--landing-bg-elevated)]' />
164+
</div>
165+
))}
166+
167+
{/* Pagination */}
168+
{totalPages > 1 && (
169+
<div className='px-6 py-8'>
170+
<div className='flex items-center justify-center gap-3'>
171+
{pageNum > 1 && (
172+
<Link
173+
href={`/blog?page=${pageNum - 1}${tag ? `&tag=${encodeURIComponent(tag)}` : ''}`}
174+
className='rounded-[5px] border border-[var(--landing-border-strong)] px-3 py-1 text-[var(--landing-text)] text-sm transition-colors hover:bg-[var(--landing-bg-elevated)]'
175+
>
176+
Previous
177+
</Link>
178+
)}
179+
<span className='text-[var(--landing-text-muted)] text-sm'>
180+
Page {pageNum} of {totalPages}
181+
</span>
182+
{pageNum < totalPages && (
183+
<Link
184+
href={`/blog?page=${pageNum + 1}${tag ? `&tag=${encodeURIComponent(tag)}` : ''}`}
185+
className='rounded-[5px] border border-[var(--landing-border-strong)] px-3 py-1 text-[var(--landing-text)] text-sm transition-colors hover:bg-[var(--landing-bg-elevated)]'
186+
>
187+
Next
188+
</Link>
189+
)}
190+
</div>
191+
</div>
192+
)}
193+
</div>
194+
195+
{/* Full-width bottom line — overlaps last inner divider to avoid double border */}
196+
<div className='-mt-px h-px w-full bg-[var(--landing-bg-elevated)]' />
197+
</section>
97198
)
98199
}

apps/sim/app/(landing)/components/features/features.tsx

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -117,36 +117,6 @@ function ScrollLetter({ scrollYProgress, charIndex, children }: ScrollLetterProp
117117
return <motion.span style={{ opacity }}>{children}</motion.span>
118118
}
119119

120-
function DotGrid({
121-
cols,
122-
rows,
123-
width,
124-
borderLeft,
125-
}: {
126-
cols: number
127-
rows: number
128-
width?: number
129-
borderLeft?: boolean
130-
}) {
131-
return (
132-
<div
133-
aria-hidden='true'
134-
className={`h-full shrink-0 bg-[var(--landing-bg-section)] p-1.5 ${borderLeft ? 'border-[var(--divider)] border-l' : ''}`}
135-
style={{
136-
width: width ? `${width}px` : undefined,
137-
display: 'grid',
138-
gridTemplateColumns: `repeat(${cols}, 1fr)`,
139-
gap: 4,
140-
placeItems: 'center',
141-
}}
142-
>
143-
{Array.from({ length: cols * rows }, (_, i) => (
144-
<div key={i} className='h-[1.5px] w-[1.5px] rounded-full bg-[#DEDEDE]' />
145-
))}
146-
</div>
147-
)
148-
}
149-
150120
export default function Features() {
151121
const sectionRef = useRef<HTMLDivElement>(null)
152122
const [activeTab, setActiveTab] = useState(0)
@@ -224,14 +194,10 @@ export default function Features() {
224194
/>
225195

226196
<div className='flex h-[68px] border border-[var(--divider)] lg:overflow-hidden'>
227-
<div className='h-full shrink-0'>
228-
<div className='h-full lg:hidden'>
229-
<DotGrid cols={3} rows={8} width={24} />
230-
</div>
231-
<div className='hidden h-full lg:block'>
232-
<DotGrid cols={8} rows={8} width={64} />
233-
</div>
234-
</div>
197+
<div
198+
aria-hidden='true'
199+
className='h-full w-[24px] shrink-0 bg-[var(--landing-bg-section)] lg:w-16'
200+
/>
235201

236202
<div role='tablist' aria-label='Feature categories' className='flex flex-1'>
237203
{FEATURE_TABS.map((tab, index) => (
@@ -275,14 +241,10 @@ export default function Features() {
275241
))}
276242
</div>
277243

278-
<div className='h-full shrink-0'>
279-
<div className='h-full lg:hidden'>
280-
<DotGrid cols={3} rows={8} width={24} />
281-
</div>
282-
<div className='hidden h-full lg:block'>
283-
<DotGrid cols={8} rows={8} width={64} />
284-
</div>
285-
</div>
244+
<div
245+
aria-hidden='true'
246+
className='h-full w-[24px] shrink-0 border-[var(--divider)] border-l bg-[var(--landing-bg-section)] lg:w-16'
247+
/>
286248
</div>
287249

288250
<div

apps/sim/app/(landing)/components/hero/hero.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default function Hero() {
4646
</h1>
4747
<p
4848
itemProp='description'
49-
className='max-w-[280px] text-center font-[430] font-season text-[color-mix(in_srgb,var(--landing-text-subtle)_60%,transparent)] text-lg leading-[125%] tracking-[0.02em] sm:max-w-none lg:text-xl'
49+
className='whitespace-nowrap text-center font-[430] font-season text-[4.4vw] text-[color-mix(in_srgb,var(--landing-text-subtle)_60%,transparent)] leading-[125%] tracking-[0.02em] sm:whitespace-normal sm:text-lg lg:text-xl'
5050
>
5151
Sim is the AI Workspace for Agent Builders
5252
</p>

0 commit comments

Comments
 (0)