Skip to content

Commit 06eef69

Browse files
Ajit Pratap Singhclaude
authored andcommitted
feat(website): comprehensive website revamp — performance, design, UX, new pages
Major overhaul of the GoSQLX website driven by a full audit (Lighthouse, accessibility, competitive analysis, performance traces, mobile UX testing). Performance: - Convert 7 homepage components from client to server components - Replace Framer Motion FadeIn with lightweight CSS IntersectionObserver (FadeInCSS) - Extract GitHubStarButton/GitHubStarCount as tiny client islands - Expected LCP improvement from ~893ms to <400ms Design System: - 12 new semantic design tokens (bg, brand, text, border layers) - Glass cards: increased opacity, inset highlight, deeper shadows - Typography: Space Grotesk (headings) + Inter (body), JetBrains Mono (code) - Prose contrast improved (body opacity 0.7 → 0.8) New Pages & Sections: - /compare/ — Feature matrix + perf bar chart vs pg_query, vitess, sqlparser - DialectShowcase — 8 dialect cards with compliance % and status badges - PerformanceSection — Animated horizontal bar chart (CSS-only, scroll-triggered) - TrustSection — 5 metric cards + 3 integration cards (Claude, VS Code, Cursor) - Hero MiniPlayground — Live WASM-powered SQL parser embedded in hero Docs & UX: - Cmd+K search modal with Fuse.js (SearchModal + search-index) - Code block CopyButton (hover-to-reveal, clipboard feedback) - DocNavigation (prev/next article links) - Reading time estimate on articles - Mobile sidebar scroll lock Accessibility (Lighthouse 96 → targeting 100): - Logo alt text, cursor-pointer on interactive elements - Mobile menu: body scroll lock + full opacity background - Text contrast: zinc-300 → zinc-200 on cards, code font 13→14px Dark/Light Mode: - ThemeToggle with localStorage persistence + system preference detection - Inline script prevents flash of wrong theme - Full light mode CSS token overrides Benchmarks: - Visual bar charts (ParseChart, CompetitorChart) above tables - Tables in collapsible "View raw data" toggles Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 54b3c66 commit 06eef69

40 files changed

Lines changed: 1997 additions & 353 deletions

website/src/app/benchmarks/BenchmarksContent.tsx

Lines changed: 136 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
'use client';
22

3+
import { useState } from 'react';
34
import { FadeIn } from '@/components/ui/FadeIn';
45
import { GlassCard } from '@/components/ui/GlassCard';
56
import { Button } from '@/components/ui/Button';
7+
import { ParseChart } from '@/components/benchmarks/ParseChart';
8+
import { CompetitorChart } from '@/components/benchmarks/CompetitorChart';
69

710
const metrics = [
811
{ label: 'Sustained Ops/sec', value: '1.38M+' },
@@ -26,6 +29,38 @@ const methodology = [
2629
'Results averaged over 5 consecutive runs to reduce variance',
2730
];
2831

32+
function RawDataToggle({ id, children }: { id: string; children: React.ReactNode }) {
33+
const [open, setOpen] = useState(false);
34+
35+
return (
36+
<div className="mt-4">
37+
<button
38+
type="button"
39+
onClick={() => setOpen((prev) => !prev)}
40+
className="text-xs text-zinc-500 hover:text-zinc-300 transition-colors flex items-center gap-1"
41+
aria-expanded={open}
42+
aria-controls={`raw-data-${id}`}
43+
>
44+
<svg
45+
className={`w-3 h-3 transition-transform duration-200 ${open ? 'rotate-90' : ''}`}
46+
fill="none"
47+
viewBox="0 0 24 24"
48+
stroke="currentColor"
49+
strokeWidth={2}
50+
>
51+
<path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" />
52+
</svg>
53+
{open ? 'Hide' : 'View'} raw data
54+
</button>
55+
{open && (
56+
<div id={`raw-data-${id}`} className="mt-3">
57+
{children}
58+
</div>
59+
)}
60+
</div>
61+
);
62+
}
63+
2964
function renderMethodologyItem(item: string) {
3065
const FLAG = '-benchmem';
3166
const idx = item.indexOf(FLAG);
@@ -75,110 +110,121 @@ export function BenchmarksContent() {
75110
</div>
76111
</section>
77112

78-
{/* Benchmark Table */}
113+
{/* Parse Benchmarks Chart + Table */}
79114
<section className="section-padding pb-16">
80115
<div className="container-width">
81116
<FadeIn>
82117
<h2 className="text-2xl font-bold text-white mb-4">Parse Benchmarks</h2>
83-
<GlassCard className="p-0 overflow-hidden" hover={false}>
84-
<div className="overflow-x-auto">
85-
<table className="w-full text-sm text-left">
86-
<caption className="sr-only">GoSQLX Parse Benchmarks</caption>
87-
<thead>
88-
<tr className="border-b border-white/[0.06]">
89-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Benchmark</th>
90-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Query Type</th>
91-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Apple M4</th>
92-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Baseline (CI)</th>
93-
</tr>
94-
</thead>
95-
<tbody>
96-
{benchmarks.map((b) => (
97-
<tr
98-
key={b.name}
99-
className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors"
100-
>
101-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-white font-medium">{b.name}</td>
102-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">{b.query}</td>
103-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono">{b.m4}</td>
104-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">{b.baseline}</td>
105-
</tr>
106-
))}
107-
</tbody>
108-
</table>
109-
</div>
118+
<GlassCard className="p-6" hover={false}>
119+
<ParseChart />
110120
</GlassCard>
111-
<p className="text-xs text-zinc-500 mt-2 md:hidden">&larr; Swipe to see all columns &rarr;</p>
121+
122+
<RawDataToggle id="parse">
123+
<GlassCard className="p-0 overflow-hidden" hover={false}>
124+
<div className="overflow-x-auto">
125+
<table className="w-full text-sm text-left">
126+
<caption className="sr-only">GoSQLX Parse Benchmarks</caption>
127+
<thead>
128+
<tr className="border-b border-white/[0.06]">
129+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Benchmark</th>
130+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Query Type</th>
131+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Apple M4</th>
132+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Baseline (CI)</th>
133+
</tr>
134+
</thead>
135+
<tbody>
136+
{benchmarks.map((b) => (
137+
<tr
138+
key={b.name}
139+
className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors"
140+
>
141+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-white font-medium">{b.name}</td>
142+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">{b.query}</td>
143+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono">{b.m4}</td>
144+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">{b.baseline}</td>
145+
</tr>
146+
))}
147+
</tbody>
148+
</table>
149+
</div>
150+
</GlassCard>
151+
<p className="text-xs text-zinc-500 mt-2 md:hidden">&larr; Swipe to see all columns &rarr;</p>
152+
</RawDataToggle>
112153
</FadeIn>
113154
</div>
114155
</section>
115156

116-
{/* Competitor Comparison */}
157+
{/* Competitor Comparison Chart + Table */}
117158
<section className="section-padding pb-16">
118159
<div className="container-width">
119160
<FadeIn>
120161
<h2 className="text-2xl font-bold text-white mb-6">Competitor Comparison</h2>
121-
<GlassCard className="p-0 overflow-hidden" hover={false}>
122-
<div className="overflow-x-auto">
123-
<table className="w-full text-sm text-left">
124-
<caption className="sr-only">Competitor Library Comparison</caption>
125-
<thead>
126-
<tr className="border-b border-white/[0.06]">
127-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Library</th>
128-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Language</th>
129-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Ops/sec</th>
130-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Memory/op</th>
131-
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Zero-copy</th>
132-
</tr>
133-
</thead>
134-
<tbody>
135-
<tr className="border-b border-white/[0.04] transition-colors bg-indigo-500/10 border-l-2 border-l-indigo-500">
136-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-white font-medium">
137-
GoSQLX{' '}
138-
<span className="ml-2 inline-block rounded-full bg-indigo-500/20 px-2 py-0.5 text-xs font-medium text-indigo-300">
139-
This Library
140-
</span>
141-
</td>
142-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
143-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono">1.38M+</td>
144-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300">Low</td>
145-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-accent-green font-medium">
146-
<span aria-label="Yes"></span>
147-
</td>
148-
</tr>
149-
<tr className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors">
150-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium">xwb1989/sqlparser</td>
151-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
152-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">~380K</td>
153-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Higher</td>
154-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-500">
155-
<span aria-label="No"></span>
156-
</td>
157-
</tr>
158-
<tr className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors">
159-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium">pg_query_go</td>
160-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
161-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">~220K</td>
162-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Higher (CGo)</td>
163-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-500">
164-
<span aria-label="No"></span>
165-
</td>
166-
</tr>
167-
<tr className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors">
168-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium">blastrain/sqlparser</td>
169-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
170-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">~290K</td>
171-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Medium</td>
172-
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-500">
173-
<span aria-label="No"></span>
174-
</td>
175-
</tr>
176-
</tbody>
177-
</table>
178-
</div>
162+
<GlassCard className="p-6" hover={false}>
163+
<CompetitorChart />
179164
</GlassCard>
180-
<p className="text-xs text-zinc-500 mt-2 md:hidden">&larr; Swipe to see all columns &rarr;</p>
181-
<p className="text-xs text-zinc-500 mt-2">* Competitor figures estimated from published benchmarks on equivalent hardware. Results may vary by query complexity.</p>
165+
166+
<RawDataToggle id="competitor">
167+
<GlassCard className="p-0 overflow-hidden" hover={false}>
168+
<div className="overflow-x-auto">
169+
<table className="w-full text-sm text-left">
170+
<caption className="sr-only">Competitor Library Comparison</caption>
171+
<thead>
172+
<tr className="border-b border-white/[0.06]">
173+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Library</th>
174+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Language</th>
175+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Ops/sec</th>
176+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Memory/op</th>
177+
<th scope="col" className="px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400">Zero-copy</th>
178+
</tr>
179+
</thead>
180+
<tbody>
181+
<tr className="border-b border-white/[0.04] transition-colors bg-indigo-500/10 border-l-2 border-l-indigo-500">
182+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-white font-medium">
183+
GoSQLX{' '}
184+
<span className="ml-2 inline-block rounded-full bg-indigo-500/20 px-2 py-0.5 text-xs font-medium text-indigo-300">
185+
This Library
186+
</span>
187+
</td>
188+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
189+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono">1.38M+</td>
190+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300">Low</td>
191+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-accent-green font-medium">
192+
<span aria-label="Yes">{'\u2713'}</span>
193+
</td>
194+
</tr>
195+
<tr className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors">
196+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium">xwb1989/sqlparser</td>
197+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
198+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">~380K</td>
199+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Higher</td>
200+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-500">
201+
<span aria-label="No">{'\u2717'}</span>
202+
</td>
203+
</tr>
204+
<tr className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors">
205+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium">pg_query_go</td>
206+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
207+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">~220K</td>
208+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Higher (CGo)</td>
209+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-500">
210+
<span aria-label="No">{'\u2717'}</span>
211+
</td>
212+
</tr>
213+
<tr className="border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors">
214+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium">blastrain/sqlparser</td>
215+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Go</td>
216+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono">~290K</td>
217+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-400">Medium</td>
218+
<td className="px-3 py-3 sm:px-6 sm:py-4 text-zinc-500">
219+
<span aria-label="No">{'\u2717'}</span>
220+
</td>
221+
</tr>
222+
</tbody>
223+
</table>
224+
</div>
225+
</GlassCard>
226+
<p className="text-xs text-zinc-500 mt-2 md:hidden">&larr; Swipe to see all columns &rarr;</p>
227+
</RawDataToggle>
182228
</FadeIn>
183229
</div>
184230
</section>

0 commit comments

Comments
 (0)