Skip to content

Commit 704f56c

Browse files
zknprclaude
andauthored
Feat/implement 5 improvements (#111)
* fix: address code review suggestions for PR #108 1. cellEditBehavior precedence: Move VS Code env config read after state restoration so extension settings override restored webview state. If the user changes the setting while a tab is hidden, the new value takes effect on re-show. 2. Unit tests: Add tests for getNodeFs() (returns fs module in Node.js, returns same reference on repeated calls) and LogEnvelope processing (onLog callback invoked with correct args, silent drop without callback). 3. JSDoc cleanup: Remove duplicate processProtocolMessage JSDoc block in rpc.ts and consolidate into single comment with onLog parameter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update CLAUDE.md with 8 stale fixes and missing patterns Stale fixes: - Uint8Array serialization: document Base64 format as preferred, array as legacy - saveCellEdit: fix reference from backendApi.exec() to backendApi.updateCell() - Web demo paths: website/public/demo/ → website/public/sqlite-viewer/ - Worker loading: webWorker.ts → workerFactory.ts (file doesn't exist) - Worker logging: document RPC LogEnvelope routing to output channel - retainContextWhenHidden: now false, document setState/getState flow Missing content added: - Key files: json-utils, cancellation-utils, serialization, documentRegistry, webviewMessageHandler, webview-collection - Patterns: webview state persistence, getNodeFs(), json_patch() optimization with runtime fallback, queryBatch for batched IPC Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: Enhance UI components with editorial styles and improved layouts - Demos: Updated video showcase with editorial heading, improved hover effects, and refined layout. - Features: Redesigned feature cards with accent colors, serif headings, and enhanced responsiveness. - Footer: Revamped footer with a warm background, serif branding, and mono-styled links for a refined look. - Hero: Transformed hero section with a gradient mesh background, left-aligned badge, and staggered animations. - Installation: Styled code blocks with editorial headings and accent-colored step numbers for clarity. - Tailwind: Updated color palette and animations for a more cohesive design. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 210ed10 commit 704f56c

9 files changed

Lines changed: 384 additions & 423 deletions

File tree

website/app/demo/DemoClient.tsx

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -480,45 +480,45 @@ export default function DemoClient() {
480480
// -------------------------------------------------------------------------
481481

482482
return (
483-
<div className="min-h-screen bg-[var(--background)] text-[var(--foreground)] flex flex-col">
483+
<div className="min-h-screen bg-[var(--ui-bg)] text-[var(--ui-fg)] flex flex-col">
484484
{/* Header */}
485-
<header className="border-b border-[var(--border)] px-6 py-4 flex items-center justify-between">
485+
<header className="border-b border-[var(--ui-edge)] px-6 py-4 flex items-center justify-between">
486486
<div className="flex items-center gap-4">
487487
<a
488488
href="/"
489-
className="flex items-center gap-2 text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors"
489+
className="flex items-center gap-2 text-[var(--ui-subtle-fg)] hover:text-[var(--ui-fg)] transition-colors"
490490
>
491491
<ArrowLeft className="w-4 h-4" />
492492
<span className="text-sm">Back</span>
493493
</a>
494-
<div className="h-6 w-px bg-[var(--border)]" />
494+
<div className="h-6 w-px bg-[var(--ui-edge)]" />
495495
<div className="flex items-center gap-2">
496-
<Database className="w-5 h-5 text-[var(--accent)]" />
496+
<Database className="w-5 h-5 text-[var(--ui-accent)]" />
497497
<h1 className="text-lg font-semibold">SQLite Explorer Demo</h1>
498498
</div>
499499
</div>
500500

501501
<div className="flex items-center gap-4">
502502
{status === 'ready' && (
503503
<>
504-
<span className="text-sm text-[var(--muted-foreground)]">{databaseName}</span>
504+
<span className="text-sm text-[var(--ui-subtle-fg)]">{databaseName}</span>
505505
<button
506506
onClick={handleReload}
507-
className="p-2 text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors"
507+
className="p-2 text-[var(--ui-subtle-fg)] hover:text-[var(--ui-fg)] transition-colors"
508508
title="Reload database"
509509
>
510510
<RefreshCw className="w-4 h-4" />
511511
</button>
512512
<button
513513
onClick={handleDownload}
514-
className="p-2 text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors"
514+
className="p-2 text-[var(--ui-subtle-fg)] hover:text-[var(--ui-fg)] transition-colors"
515515
title="Download database"
516516
>
517517
<Download className="w-4 h-4" />
518518
</button>
519519
<button
520520
onClick={handleClose}
521-
className="px-3 py-1.5 text-sm bg-[var(--muted)] hover:opacity-80 rounded-md transition-colors"
521+
className="px-3 py-1.5 text-sm bg-[var(--ui-subtle)] hover:opacity-80 rounded-md transition-colors"
522522
>
523523
Close
524524
</button>
@@ -528,7 +528,7 @@ export default function DemoClient() {
528528
href="https://github.com/zknpr/sqlite-explorer"
529529
target="_blank"
530530
rel="noopener noreferrer"
531-
className="p-2 text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors"
531+
className="p-2 text-[var(--ui-subtle-fg)] hover:text-[var(--ui-fg)] transition-colors"
532532
>
533533
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
534534
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
@@ -547,8 +547,8 @@ export default function DemoClient() {
547547
relative w-full max-w-xl p-12 border-2 border-dashed rounded-xl
548548
transition-all duration-200 cursor-pointer
549549
${isDragOver
550-
? 'border-[var(--accent)] bg-[var(--accent)]/10'
551-
: 'border-[var(--border)] hover:border-[var(--muted-foreground)] hover:bg-[var(--muted)]/50'
550+
? 'border-[var(--ui-accent)] bg-[var(--ui-accent)]/10'
551+
: 'border-[var(--ui-edge)] hover:border-[var(--ui-subtle-fg)] hover:bg-[var(--ui-subtle)]/50'
552552
}
553553
`}
554554
onDragOver={handleDragOver}
@@ -568,14 +568,14 @@ export default function DemoClient() {
568568
}}
569569
/>
570570
<div className="flex flex-col items-center text-center">
571-
<div className="w-16 h-16 rounded-full bg-[var(--muted)] flex items-center justify-center mb-4">
572-
<Upload className="w-8 h-8 text-[var(--muted-foreground)]" />
571+
<div className="w-16 h-16 rounded-full bg-[var(--ui-subtle)] flex items-center justify-center mb-4">
572+
<Upload className="w-8 h-8 text-[var(--ui-subtle-fg)]" />
573573
</div>
574574
<h2 className="text-xl font-semibold mb-2">Drop your SQLite database</h2>
575-
<p className="text-[var(--muted-foreground)] mb-4">
575+
<p className="text-[var(--ui-subtle-fg)] mb-4">
576576
or click to browse (.db, .sqlite, .sqlite3)
577577
</p>
578-
<div className="inline-flex items-center gap-2 px-4 py-2 bg-[var(--accent)] text-[var(--accent-foreground)] hover:opacity-90 rounded-lg transition-colors">
578+
<div className="inline-flex items-center gap-2 px-4 py-2 bg-[var(--ui-accent)] text-[var(--ui-accent-fg)] hover:opacity-90 rounded-lg transition-colors">
579579
<FileUp className="w-4 h-4" />
580580
<span>Choose File</span>
581581
</div>
@@ -584,29 +584,29 @@ export default function DemoClient() {
584584

585585
{/* Sample Databases */}
586586
<div className="mt-12 w-full max-w-xl">
587-
<h3 className="text-sm font-medium text-[var(--muted-foreground)] mb-4 uppercase tracking-wide">
587+
<h3 className="text-sm font-medium text-[var(--ui-subtle-fg)] mb-4 uppercase tracking-wide">
588588
Or try a sample database
589589
</h3>
590590
<div className="grid gap-3">
591591
{SAMPLE_DATABASES.map((db) => (
592592
<button
593593
key={db.name}
594594
onClick={() => loadSampleDatabase(db.url, `${db.name.toLowerCase()}.db`)}
595-
className="flex items-center gap-4 p-4 bg-[var(--muted)] hover:opacity-80 border border-[var(--border)] hover:border-[var(--muted-foreground)] rounded-lg transition-colors text-left"
595+
className="flex items-center gap-4 p-4 bg-[var(--ui-subtle)] hover:opacity-80 border border-[var(--ui-edge)] hover:border-[var(--ui-subtle-fg)] rounded-lg transition-colors text-left"
596596
>
597-
<Database className="w-8 h-8 text-[var(--accent)] shrink-0" />
597+
<Database className="w-8 h-8 text-[var(--ui-accent)] shrink-0" />
598598
<div className="flex-1 min-w-0">
599599
<div className="font-medium">{db.name}</div>
600-
<div className="text-sm text-[var(--muted-foreground)]">{db.description}</div>
600+
<div className="text-sm text-[var(--ui-subtle-fg)]">{db.description}</div>
601601
</div>
602-
<div className="text-sm text-[var(--muted-foreground)]">{db.size}</div>
602+
<div className="text-sm text-[var(--ui-subtle-fg)]">{db.size}</div>
603603
</button>
604604
))}
605605
</div>
606606
</div>
607607

608608
{/* Info Box */}
609-
<div className="mt-12 max-w-xl text-center text-sm text-[var(--muted-foreground)]">
609+
<div className="mt-12 max-w-xl text-center text-sm text-[var(--ui-subtle-fg)]">
610610
<p>
611611
Your database runs entirely in your browser using WebAssembly.
612612
No data is sent to any server.
@@ -617,8 +617,8 @@ export default function DemoClient() {
617617

618618
{status === 'loading' && (
619619
<div className="flex-1 flex flex-col items-center justify-center">
620-
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[var(--accent)] mb-4" />
621-
<p className="text-[var(--muted-foreground)]">Loading database...</p>
620+
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[var(--ui-accent)] mb-4" />
621+
<p className="text-[var(--ui-subtle-fg)]">Loading database...</p>
622622
</div>
623623
)}
624624

@@ -628,12 +628,12 @@ export default function DemoClient() {
628628
<AlertCircle className="w-8 h-8 text-red-500" />
629629
</div>
630630
<h2 className="text-xl font-semibold mb-2">Failed to load database</h2>
631-
<p className="text-[var(--muted-foreground)] mb-6 text-center max-w-md">
631+
<p className="text-[var(--ui-subtle-fg)] mb-6 text-center max-w-md">
632632
{errorMessage || 'An unknown error occurred'}
633633
</p>
634634
<button
635635
onClick={handleClose}
636-
className="px-4 py-2 bg-[var(--muted)] hover:opacity-80 rounded-lg transition-colors"
636+
className="px-4 py-2 bg-[var(--ui-subtle)] hover:opacity-80 rounded-lg transition-colors"
637637
>
638638
Try Again
639639
</button>

website/app/globals.css

Lines changed: 85 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,45 @@
11
/**
2-
* Global CSS Variables and Base Styles
2+
* SQLite Explorer — Design Tokens & Base Styles
33
*
4-
* Design system following minimal/professional aesthetic (Vercel-inspired).
5-
* Uses CSS custom properties for theme switching support.
4+
* "Editorial Developer" aesthetic:
5+
* - Warm off-white base with teal accents
6+
* - Instrument Serif headings, Inter body, JetBrains Mono code
7+
* - Dot-grid texture on alternating sections
8+
* - Subtle noise grain for depth
69
*/
710

811
@tailwind base;
912
@tailwind components;
1013
@tailwind utilities;
1114

1215
:root {
13-
/* Light theme (default) */
14-
--background: #ffffff;
15-
--foreground: #171717;
16-
--muted: #f5f5f5;
17-
--muted-foreground: #737373;
18-
--border: #e5e5e5;
19-
--accent: #0070f3;
20-
--accent-foreground: #ffffff;
21-
22-
/* Typography */
23-
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
24-
--font-mono: 'SF Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', monospace;
16+
--ui-bg: #fafaf8;
17+
--ui-fg: #1a1a18;
18+
--ui-subtle: #f0efeb;
19+
--ui-subtle-fg: #6b6b63;
20+
--ui-edge: #ddddd5;
21+
--ui-accent: #0d9488;
22+
--ui-accent-fg: #ffffff;
23+
--ui-accent-soft: #0d948815;
24+
25+
--font-sans: var(--font-inter), -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
26+
--font-display: var(--font-instrument), Georgia, 'Times New Roman', serif;
27+
--font-mono: var(--font-jb-mono), 'SF Mono', 'Fira Code', monospace;
2528
}
2629

2730
.dark {
28-
/* Dark theme */
29-
--background: #0a0a0a;
30-
--foreground: #ededed;
31-
--muted: #1a1a1a;
32-
--muted-foreground: #a3a3a3;
33-
--border: #262626;
34-
--accent: #0070f3;
35-
--accent-foreground: #ffffff;
31+
--ui-bg: #0c0c0b;
32+
--ui-fg: #e8e8e2;
33+
--ui-subtle: #161614;
34+
--ui-subtle-fg: #9a9a90;
35+
--ui-edge: #2a2a26;
36+
--ui-accent: #2dd4bf;
37+
--ui-accent-fg: #0c0c0b;
38+
--ui-accent-soft: #2dd4bf15;
3639
}
3740

38-
/* Base styles */
41+
/* ─── Base ─── */
42+
3943
* {
4044
box-sizing: border-box;
4145
padding: 0;
@@ -48,55 +52,81 @@ body {
4852
overflow-x: hidden;
4953
}
5054

55+
html {
56+
scroll-behavior: smooth;
57+
}
58+
5159
body {
52-
background-color: var(--background);
53-
color: var(--foreground);
60+
background-color: var(--ui-bg);
61+
color: var(--ui-fg);
5462
font-family: var(--font-sans);
5563
-webkit-font-smoothing: antialiased;
5664
-moz-osx-font-smoothing: grayscale;
5765
}
5866

59-
/* Utility classes */
60-
@layer utilities {
61-
.text-balance {
62-
text-wrap: balance;
63-
}
67+
/* ─── Typography ─── */
6468

65-
.text-gradient {
66-
background: linear-gradient(to right, var(--foreground), var(--muted-foreground));
67-
-webkit-background-clip: text;
68-
-webkit-text-fill-color: transparent;
69-
background-clip: text;
70-
}
69+
h1, h2, h3 {
70+
font-family: var(--font-display);
71+
font-weight: 400;
72+
letter-spacing: -0.01em;
73+
}
74+
75+
code {
76+
font-family: var(--font-mono);
77+
font-size: 0.85em;
78+
background-color: var(--ui-accent-soft);
79+
color: var(--ui-accent);
80+
padding: 0.15em 0.4em;
81+
border-radius: 0.25rem;
7182
}
7283

73-
/* Selection styling */
84+
pre code {
85+
background-color: transparent;
86+
color: inherit;
87+
padding: 0;
88+
}
89+
90+
/* ─── Selection ─── */
91+
7492
::selection {
75-
background-color: var(--accent);
76-
color: var(--accent-foreground);
93+
background-color: var(--ui-accent);
94+
color: var(--ui-accent-fg);
7795
}
7896

79-
/* Focus styles for accessibility */
8097
:focus-visible {
81-
outline: 2px solid var(--accent);
98+
outline: 2px solid var(--ui-accent);
8299
outline-offset: 2px;
83100
}
84101

85-
/* Smooth scrolling */
86-
html {
87-
scroll-behavior: smooth;
102+
/* ─── Dot Grid Background ─── */
103+
104+
.dot-grid {
105+
background-image: radial-gradient(circle, var(--ui-edge) 1px, transparent 1px);
106+
background-size: 24px 24px;
88107
}
89108

90-
/* Code blocks */
91-
code {
92-
font-family: var(--font-mono);
93-
font-size: 0.875em;
94-
background-color: var(--muted);
95-
padding: 0.2em 0.4em;
96-
border-radius: 0.25rem;
109+
/* ─── Noise Grain Overlay ─── */
110+
111+
.grain::after {
112+
content: '';
113+
position: absolute;
114+
inset: 0;
115+
pointer-events: none;
116+
opacity: 0.03;
117+
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
118+
background-repeat: repeat;
119+
background-size: 256px 256px;
97120
}
98121

99-
pre code {
100-
background-color: transparent;
101-
padding: 0;
122+
.dark .grain::after {
123+
opacity: 0.05;
124+
}
125+
126+
/* ─── Utilities ─── */
127+
128+
@layer utilities {
129+
.text-balance {
130+
text-wrap: balance;
131+
}
102132
}

0 commit comments

Comments
 (0)