@@ -107,110 +107,133 @@ export function Demo() {
107107
108108 return (
109109 < section className = "px-6 py-24 max-w-6xl mx-auto" id = "demo" >
110- < h2 className = "text-3xl md:text-4xl font-bold text-center mb-4" >
111- Try it in your browser
112- </ h2 >
113- < p className = "text-center text-muted-foreground mb-10 max-w-xl mx-auto" >
114- Full PostgreSQL running in WebAssembly. Write real SQL — no server needed.
115- </ p >
110+ < div className = "border-t border-border/45 pt-10" >
111+ < div className = "mb-8 max-w-3xl" >
112+ < p className = "section-label mb-3" >
113+ In-browser sandbox
114+ </ p >
115+ < h2 className = "font-display text-[2.6rem] leading-[0.96] md:text-[3.9rem]" >
116+ Touch the flow
117+ < br />
118+ before you
119+ < br />
120+ install it.
121+ </ h2 >
122+ < p className = "mt-4 text-base leading-relaxed text-muted-foreground" >
123+ Full PostgreSQL running in WebAssembly. Real SQL, seeded data, no setup friction.
124+ </ p >
116125
117- { /* Sample query buttons */ }
118- < div className = "flex flex-wrap justify-center gap-2 mb-6" >
119- { SAMPLE_QUERIES . map ( ( q ) => (
120- < button
121- key = { q . label }
122- onClick = { ( ) => {
123- setSql ( q . sql ) ;
124- executeMutation . mutate ( q . sql , {
125- onSuccess : ( data ) => setResult ( data ) ,
126- } ) ;
127- } }
128- className = { `rounded-full border px-3 py-1 text-xs font-mono transition-colors ${
129- sql === q . sql
130- ? "border-primary bg-primary/10 text-primary"
131- : "border-border bg-card/60 text-muted-foreground hover:text-foreground hover:border-muted-foreground/50"
132- } `}
133- >
134- { q . label }
135- </ button >
136- ) ) }
137- </ div >
138-
139- { /* Demo window */ }
140- < div className = "glass rounded-xl overflow-hidden shadow-2xl shadow-primary/5 mx-auto max-w-5xl" >
141- { /* Title bar */ }
142- < div className = "flex items-center gap-2 px-4 py-2.5 bg-card/80 border-b border-border/50" >
143- < div className = "flex gap-1.5" >
144- < span className = "h-3 w-3 rounded-full bg-red-500/80" />
145- < span className = "h-3 w-3 rounded-full bg-yellow-500/80" />
146- < span className = "h-3 w-3 rounded-full bg-green-500/80" />
147- </ div >
148- < span className = "flex-1 text-center text-xs text-muted-foreground font-mono" >
149- RSQL — PostgreSQL (WebAssembly)
150- </ span >
151- < button
152- onClick = { ( ) => resetMutation . mutate ( ) }
153- className = "text-muted-foreground hover:text-foreground transition-colors"
154- title = "Reset database"
155- >
156- < RotateCcw className = "h-3.5 w-3.5" />
157- </ button >
158- </ div >
159-
160- { /* Content area */ }
161- < div className = "flex h-[480px]" >
162- { /* Sidebar */ }
163- < DemoSidebar
164- onTableClick = { ( table ) => {
165- const q = `SELECT * FROM ${ table } LIMIT 100;` ;
166- setSql ( q ) ;
167- executeMutation . mutate ( q , {
168- onSuccess : ( data ) => setResult ( data ) ,
169- } ) ;
170- } }
171- />
172-
173- { /* Main area */ }
174- < div className = "flex-1 flex flex-col min-w-0" >
175- { /* Toolbar */ }
176- < div className = "flex items-center gap-2 px-3 py-1.5 border-b border-border/50 bg-card/40" >
126+ < div className = "mt-6 flex flex-wrap gap-2" >
127+ { SAMPLE_QUERIES . map ( ( q ) => (
177128 < button
178- onClick = { execute }
179- disabled = { executeMutation . isPending }
180- className = "gradient-btn inline-flex items-center gap-1.5 rounded-md px-3 py-1 text-xs font-semibold text-white disabled:opacity-50"
129+ key = { q . label }
130+ onClick = { ( ) => {
131+ setSql ( q . sql ) ;
132+ executeMutation . mutate ( q . sql , {
133+ onSuccess : ( data ) => setResult ( data ) ,
134+ } ) ;
135+ } }
136+ className = { `rounded-full border px-4 py-2 text-left text-xs font-mono transition-colors ${
137+ sql === q . sql
138+ ? "border-primary bg-primary/10 text-primary"
139+ : "border-border bg-card/60 text-muted-foreground hover:text-foreground hover:border-muted-foreground/50"
140+ } `}
181141 >
182- { executeMutation . isPending ? (
183- < Loader2 className = "h-3 w-3 animate-spin" />
184- ) : (
185- < Play className = "h-3 w-3" />
186- ) }
187- Execute
142+ { q . label }
188143 </ button >
189- < span className = "text-[10px] text-muted-foreground font-mono ml-auto" >
190- { result
191- ? result . error
192- ? "Error"
193- : `${ result . rowCount } rows in ${ result . time . toFixed ( 1 ) } ms`
194- : "⌘+Enter to run" }
195- </ span >
144+ ) ) }
145+ </ div >
146+
147+ < div className = "mt-6 grid gap-3 border-t border-border/40 pt-4 sm:grid-cols-3" >
148+ < div >
149+ < div className = "font-mono text-[10px] uppercase tracking-[0.24em] text-muted-foreground" >
150+ Engine
151+ </ div >
152+ < div className = "mt-2 text-sm text-foreground" > PGlite</ div >
153+ </ div >
154+ < div >
155+ < div className = "font-mono text-[10px] uppercase tracking-[0.24em] text-muted-foreground" >
156+ Dataset
157+ </ div >
158+ < div className = "mt-2 text-sm text-foreground" > Seeded demo schema</ div >
159+ </ div >
160+ < div >
161+ < div className = "font-mono text-[10px] uppercase tracking-[0.24em] text-muted-foreground" >
162+ Setup
163+ </ div >
164+ < div className = "mt-2 text-sm text-foreground" > Zero install</ div >
196165 </ div >
166+ </ div >
167+ </ div >
197168
198- { /* Editor */ }
199- < div className = "relative flex-none h-[180px] border-b border-border/50" >
200- < textarea
201- ref = { textareaRef }
202- value = { sql }
203- onChange = { ( e ) => setSql ( e . target . value ) }
204- onKeyDown = { handleKeyDown }
205- spellCheck = { false }
206- className = "w-full h-full resize-none bg-[var(--editor-bg)] text-foreground font-mono text-[13px] leading-6 p-4 focus:outline-none"
207- placeholder = "Write your SQL here..."
208- />
169+ < div className = "section-frame overflow-hidden rounded-[28px]" >
170+ < div className = "flex items-center gap-2 px-4 py-2.5 bg-card/80 border-b border-border/50" >
171+ < div className = "flex gap-1.5" >
172+ < span className = "h-3 w-3 rounded-full bg-red-500/80" />
173+ < span className = "h-3 w-3 rounded-full bg-yellow-500/80" />
174+ < span className = "h-3 w-3 rounded-full bg-green-500/80" />
209175 </ div >
176+ < span className = "flex-1 text-center text-xs text-muted-foreground font-mono" >
177+ RSQL — browser.sandbox
178+ </ span >
179+ < button
180+ onClick = { ( ) => resetMutation . mutate ( ) }
181+ className = "text-muted-foreground hover:text-foreground transition-colors"
182+ title = "Reset database"
183+ >
184+ < RotateCcw className = "h-3.5 w-3.5" />
185+ </ button >
186+ </ div >
187+
188+ < div className = "flex h-[480px]" >
189+ < DemoSidebar
190+ onTableClick = { ( table ) => {
191+ const q = `SELECT * FROM ${ table } LIMIT 100;` ;
192+ setSql ( q ) ;
193+ executeMutation . mutate ( q , {
194+ onSuccess : ( data ) => setResult ( data ) ,
195+ } ) ;
196+ } }
197+ />
198+
199+ < div className = "flex-1 flex flex-col min-w-0" >
200+ < div className = "flex items-center gap-2 px-3 py-1.5 border-b border-border/50 bg-card/40" >
201+ < button
202+ onClick = { execute }
203+ disabled = { executeMutation . isPending }
204+ className = "gradient-btn inline-flex items-center gap-1.5 rounded-md px-3 py-1 text-xs font-semibold text-white disabled:opacity-50"
205+ >
206+ { executeMutation . isPending ? (
207+ < Loader2 className = "h-3 w-3 animate-spin" />
208+ ) : (
209+ < Play className = "h-3 w-3" />
210+ ) }
211+ Execute
212+ </ button >
213+ < span className = "text-[10px] text-muted-foreground font-mono ml-auto" >
214+ { result
215+ ? result . error
216+ ? "Error"
217+ : `${ result . rowCount } rows in ${ result . time . toFixed ( 1 ) } ms`
218+ : "⌘+Enter to run" }
219+ </ span >
220+ </ div >
210221
211- { /* Results */ }
212- < div className = "flex-1 overflow-auto" >
213- { result && < DemoResults result = { result } /> }
222+ < div className = "relative flex-none h-[180px] border-b border-border/50" >
223+ < textarea
224+ ref = { textareaRef }
225+ value = { sql }
226+ onChange = { ( e ) => setSql ( e . target . value ) }
227+ onKeyDown = { handleKeyDown }
228+ spellCheck = { false }
229+ className = "w-full h-full resize-none bg-[var(--editor-bg)] text-foreground font-mono text-[13px] leading-6 p-4 focus:outline-none"
230+ placeholder = "Write your SQL here..."
231+ />
232+ </ div >
233+
234+ < div className = "flex-1 overflow-auto" >
235+ { result && < DemoResults result = { result } /> }
236+ </ div >
214237 </ div >
215238 </ div >
216239 </ div >
@@ -357,11 +380,11 @@ function DemoResults({ result }: { result: QueryResult }) {
357380 return (
358381 < table className = "w-full text-left font-mono text-[12px] border-collapse" >
359382 < thead >
360- < tr className = "bg-muted/50 sticky top-0" >
383+ < tr >
361384 { result . columns . map ( ( col ) => (
362385 < th
363386 key = { col }
364- className = "px-3 py-1.5 text-[11px] font-semibold text-muted-foreground border-b border-r border-border/30 whitespace-nowrap "
387+ className = "sticky top-0 z-10 border-b border-r border-border/30 bg-card px-3 py-1.5 text-[11px] font-semibold whitespace-nowrap text-muted-foreground"
365388 >
366389 { col }
367390 </ th >
0 commit comments