Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions website/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Hero } from '@/components/home/Hero';
import { TrustSection } from '@/components/home/TrustSection';
import { ProofStrip } from '@/components/home/ProofStrip';
import { PerformanceSection } from '@/components/home/PerformanceSection';
import { FeatureGrid } from '@/components/home/FeatureGrid';
import { DialectShowcase } from '@/components/home/DialectShowcase';
import { CodeExamples } from '@/components/home/CodeExamples';
import { McpSection } from '@/components/home/McpSection';
import { VscodeSection } from '@/components/home/VscodeSection';
import { UseEverywhere } from '@/components/home/UseEverywhere';
import { CtaBanner } from '@/components/home/CtaBanner';
import { getStars } from '@/lib/github';
import { JsonLd } from '@/components/JsonLd';
Expand Down Expand Up @@ -75,13 +74,12 @@ export default async function Home() {
<>
<JsonLd data={homeJsonLd} />
<Hero stars={stars} />
<TrustSection stars={stars} />
<ProofStrip stars={stars} />
<PerformanceSection />
<FeatureGrid />
<DialectShowcase />
<CodeExamples />
<McpSection />
<VscodeSection />
<UseEverywhere />
<CtaBanner />
</>
);
Expand Down
8 changes: 2 additions & 6 deletions website/src/components/home/AnimatedBars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function AnimatedBars({ benchmarks, maxOps }: { benchmarks: Benchmark[];
}, []);

return (
<div ref={ref} className="space-y-4" role="img" aria-label="Performance comparison bar chart">
<div ref={ref} className="space-y-4" role="img" aria-label={`GoSQLX parse-stage throughput: ${benchmarks.map((b) => `${b.name} ${b.label}`).join(', ')}`}>
{benchmarks.map((b, i) => {
const widthPercent = (b.ops / maxOps) * 100;
return (
Expand All @@ -47,11 +47,7 @@ export function AnimatedBars({ benchmarks, maxOps }: { benchmarks: Benchmark[];
</span>
<div className="flex-1 h-8 rounded-md bg-zinc-800/50 overflow-hidden relative">
<div
className={`h-full rounded-md ${
b.highlight
? 'bg-gradient-to-r from-green-500 to-emerald-400'
: 'bg-zinc-700'
}`}
className={`h-full rounded-md ${b.highlight ? 'bg-brand' : 'bg-zinc-700'}`}
style={{
width: visible ? `${widthPercent}%` : '0%',
transition: `width 1s cubic-bezier(0.22,1,0.36,1) ${i * 0.15}s`,
Expand Down
97 changes: 46 additions & 51 deletions website/src/components/home/DialectShowcase.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,36 @@
import Link from 'next/link';
import { PROJECT, QA_CORPUS } from '@/data/metrics';
import { GlassCard } from '@/components/ui/GlassCard';
import { FadeIn } from '@/components/ui/FadeIn';

const COMPAT_HREF = '/docs/sql-compatibility/#supported-dialects';

interface Dialect {
name: string;
abbr: string;
bgColor: string;
compliance: number;
detail?: string;
status: 'Excellent' | 'Very Good' | 'Good' | 'In Progress';
/** The dialect string passed to the parser (docs/SQL_COMPATIBILITY.md, "Supported Dialects"). */
key: string;
/** QA-corpus result, only where a corpus run is recorded. No unsourced percentages. */
qa?: { pass: number; total: number };
}

const DIALECTS: Dialect[] = [
{ name: 'PostgreSQL', abbr: 'PG', bgColor: 'bg-blue-500/20', compliance: 95, status: 'Excellent' },
{ name: 'MySQL', abbr: 'My', bgColor: 'bg-orange-500/20', compliance: 95, status: 'Excellent' },
{ name: 'MariaDB', abbr: 'Ma', bgColor: 'bg-sky-500/20', compliance: 95, status: 'Excellent' },
{ name: 'SQL Server', abbr: 'MS', bgColor: 'bg-red-500/20', compliance: 85, status: 'Very Good' },
{ name: 'Oracle', abbr: 'Or', bgColor: 'bg-rose-500/20', compliance: 80, status: 'Good' },
{ name: 'SQLite', abbr: 'SL', bgColor: 'bg-emerald-500/20', compliance: 85, status: 'Very Good' },
{ name: 'Snowflake', abbr: 'SF', bgColor: 'bg-cyan-500/20', compliance: Math.round((QA_CORPUS.snowflake.pass / QA_CORPUS.snowflake.total) * 100), detail: `${QA_CORPUS.snowflake.pass}/${QA_CORPUS.snowflake.total} QA`, status: 'Excellent' },
{ name: 'ClickHouse', abbr: 'CH', bgColor: 'bg-yellow-500/20', compliance: Math.round((QA_CORPUS.clickhouse.pass / QA_CORPUS.clickhouse.total) * 100), detail: `${QA_CORPUS.clickhouse.pass}/${QA_CORPUS.clickhouse.total} QA`, status: 'Good' },
{ name: 'PostgreSQL', key: 'postgresql' },
{ name: 'MySQL', key: 'mysql' },
{ name: 'MariaDB', key: 'mariadb' },
{ name: 'SQL Server', key: 'sqlserver' },
{ name: 'Oracle', key: 'oracle' },
{ name: 'SQLite', key: 'sqlite' },
{ name: 'Snowflake', key: 'snowflake', qa: QA_CORPUS.snowflake },
{ name: 'ClickHouse', key: 'clickhouse', qa: QA_CORPUS.clickhouse },
];

const statusColors: Record<Dialect['status'], string> = {
'Excellent': 'bg-ok/10 text-ok border-ok/20',
'Very Good': 'bg-accent/10 text-accent border-accent/20',
'Good': 'bg-accent-warm/10 text-accent-warm border-accent-warm/20',
'In Progress': 'bg-fg-subtle/10 text-fg-subtle border-border',
};

function complianceColor(pct: number): string {
if (pct >= 95) return 'text-ok';
if (pct >= 85) return 'text-accent';
if (pct >= 80) return 'text-accent-warm';
return 'text-fg-subtle';
/** Neutral database glyph shared by every dialect (no vendor marks). */
function DatabaseGlyph() {
return (
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" aria-hidden="true">
<ellipse cx="12" cy="5.5" rx="7.5" ry="2.75" />
<path d="M4.5 5.5v13c0 1.5 3.4 2.75 7.5 2.75s7.5-1.25 7.5-2.75v-13M4.5 12c0 1.5 3.4 2.75 7.5 2.75s7.5-1.25 7.5-2.75" />
</svg>
);
}

export function DialectShowcase() {
Expand All @@ -45,36 +42,34 @@ export function DialectShowcase() {
{PROJECT.dialectCount} SQL Dialects, One Parser
</h2>
<p className="text-zinc-300 text-center mb-12 text-lg">
From PostgreSQL to ClickHouse — parse them all
From PostgreSQL to ClickHouse, selected with a single dialect string
</p>
</FadeIn>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{/* 8 cards: 2 columns on phones, 4 from md, so every row is full. */}
<ul className="grid grid-cols-2 md:grid-cols-4 gap-4">
{DIALECTS.map((dialect, i) => (
<FadeIn viewport key={dialect.name} delay={i * 0.08}>
<GlassCard className="p-5 h-full text-center">
<div
className={`w-11 h-11 rounded-full ${dialect.bgColor} text-fg flex items-center justify-center mx-auto mb-3 text-sm font-bold`}
>
{dialect.abbr}
</div>
<h3 className="text-sm font-semibold text-white mb-2">
{dialect.name}
</h3>
<p className={`text-2xl font-bold mb-1 ${complianceColor(dialect.compliance)}`}>
{dialect.compliance}%
</p>
{dialect.detail && (
<p className="text-xs text-fg-subtle mb-2">{dialect.detail}</p>
)}
<span
className={`inline-block text-xs font-medium px-2.5 py-0.5 rounded-full border ${statusColors[dialect.status]}`}
<li key={dialect.key}>
<FadeIn viewport delay={i * 0.05} className="h-full">
<Link
href={COMPAT_HREF}
className="glass glass-hover flex h-full flex-col items-center p-5 text-center transition-colors"
>
{dialect.status}
</span>
</GlassCard>
</FadeIn>
<span className="mb-3 flex h-11 w-11 items-center justify-center rounded-full bg-accent/10 text-accent">
<DatabaseGlyph />
</span>
<h3 className="text-sm font-semibold text-white">{dialect.name}</h3>
<code className="mt-1 text-xs text-fg-subtle">&quot;{dialect.key}&quot;</code>
<span className="mt-3 text-xs text-accent">
{dialect.qa
? `QA corpus pass ${dialect.qa.pass}/${dialect.qa.total} (${QA_CORPUS.release})`
: 'Coverage notes'}
<span aria-hidden="true"> →</span>
</span>
</Link>
</FadeIn>
</li>
))}
</div>
</ul>
</div>
</section>
);
Expand Down
2 changes: 1 addition & 1 deletion website/src/components/home/FeatureGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function FeatureGrid() {
<div className="max-w-6xl mx-auto px-4">
<FadeIn viewport>
<h2 className="text-3xl font-bold text-white text-center mb-12">
Built for Production
Everything you need to work with SQL in Go
</h2>
</FadeIn>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
Expand Down
59 changes: 0 additions & 59 deletions website/src/components/home/McpSection.tsx

This file was deleted.

48 changes: 22 additions & 26 deletions website/src/components/home/PerformanceSection.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { GlassCard } from '@/components/ui/GlassCard';
import { FadeIn } from '@/components/ui/FadeIn';
import { AnimatedCounter } from '@/components/ui/AnimatedCounter';
import { BENCH_ENV, HEADLINE_OPS_PER_SEC, PARSE_BENCHMARKS, PROJECT, formatOps, opsPerSec } from '@/data/metrics';
import { BENCH_ENV, HEADLINE_OPS_PER_SEC, PARSE_BENCHMARKS, formatOps, opsPerSec } from '@/data/metrics';
import { AnimatedBars } from './AnimatedBars';
import { ReproduceSnippet } from './ReproduceSnippet';

interface Stat {
/** Animated numeric value; omit when `text` is shown instead. */
value?: number;
/** Static text for figures that are ranges or estimates. */
text?: string;
suffix?: string;
/** Compact display string, short enough to fit a narrow card. */
display: string;
label: string;
color: string;
prefix?: string;
}

const [simpleSelect] = PARSE_BENCHMARKS;
const complexQuery = PARSE_BENCHMARKS.find((b) => b.name === 'Complex Query') ?? PARSE_BENCHMARKS[PARSE_BENCHMARKS.length - 1];

/* Every figure is parse stage only (pre-tokenized input -> AST); hardware and Go version are in the caption. */
const stats: Stat[] = [
{ value: HEADLINE_OPS_PER_SEC, suffix: '', label: `parses/sec (simple SELECT, parse stage, ${BENCH_ENV.hardware})`, color: 'text-accent-warm', prefix: '~' },
{ value: PARSE_BENCHMARKS[0].nsPerOp, suffix: 'ns', label: 'parse latency (simple SELECT, parse stage)', color: 'text-accent' },
{ text: PROJECT.sql99, label: 'SQL-99 compliance (estimated)', color: 'text-brand' },
{ value: PROJECT.dialectCount, suffix: '', label: 'Dialects', color: 'text-accent' },
{ display: `~${formatOps(HEADLINE_OPS_PER_SEC)}`, label: 'parses/sec, simple SELECT (parse stage)' },
{ display: `${simpleSelect.nsPerOp.toLocaleString('en-US')}ns`, label: 'latency, simple SELECT (parse stage)' },
{ display: `~${formatOps(opsPerSec(complexQuery.nsPerOp))}`, label: 'parses/sec, complex query (parse stage)' },
{ display: `${complexQuery.nsPerOp.toLocaleString('en-US')}ns`, label: 'latency, complex query (parse stage)' },
];

const benchmarks = PARSE_BENCHMARKS.map((b) => ({
Expand All @@ -42,19 +41,12 @@ export function PerformanceSection() {
</FadeIn>

{/* Stat cards */}
<div className="grid grid-cols-2 sm:grid-cols-4 gap-4 md:gap-8">
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6">
{stats.map((stat, i) => (
<FadeIn viewport key={stat.label} delay={i * 0.1}>
<GlassCard className="p-6 text-center w-full">
<div className="flex items-baseline justify-center gap-0.5">
{stat.prefix && (
<span className={`text-3xl sm:text-4xl font-bold ${stat.color}`}>{stat.prefix}</span>
)}
{stat.value !== undefined ? (
<AnimatedCounter value={stat.value} suffix={stat.suffix} color={stat.color} />
) : (
<span className={`text-3xl sm:text-4xl font-bold tabular-nums ${stat.color}`}>{stat.text}</span>
)}
<FadeIn viewport key={stat.label} delay={i * 0.1} className="h-full">
<GlassCard className="p-4 sm:p-6 text-center w-full h-full">
<div className="text-2xl sm:text-3xl xl:text-4xl font-bold tabular-nums text-fg whitespace-nowrap">
{stat.display}
</div>
<p className="text-sm text-zinc-200 mt-1">{stat.label}</p>
</GlassCard>
Expand All @@ -68,8 +60,12 @@ export function PerformanceSection() {
<AnimatedBars benchmarks={benchmarks} maxOps={maxOps} />
<p className="text-xs text-zinc-400 mt-6 text-center">
Parse stage only (not tokenize or end-to-end), {BENCH_ENV.hardware}, {BENCH_ENV.goVersion}.
Source: BenchmarkPerformanceBaseline, median of 10 runs.
Source: {BENCH_ENV.source}.
</p>
<div className="mt-6">
<h3 className="text-sm font-semibold text-zinc-200 mb-2">Reproduce</h3>
<ReproduceSnippet command={BENCH_ENV.command} />
</div>
</GlassCard>
</FadeIn>
</div>
Expand Down
Loading
Loading