feat(viz): sprint 1 - array visualisations

This commit is contained in:
2025-08-24 16:09:24 +01:00
parent 21227628fa
commit 68e5e95dda
13 changed files with 2702 additions and 187 deletions

View File

@@ -1,19 +1,71 @@
@import "tailwindcss";
/* Register theme tokens with Tailwind so utility classes work */
@theme {
--color-background: var(--background);
--color-background-subtle: var(--background-subtle);
--color-surface: var(--surface);
--color-surface-variant: var(--surface-variant);
--color-surface-subtle: var(--surface-subtle);
--color-border: var(--border);
--color-border-focus: var(--border-focus);
--color-border-disabled: var(--border-disabled);
--color-foreground: var(--foreground);
--color-foreground-muted: var(--foreground-muted);
--color-primary: var(--primary);
--color-primary-hover: var(--primary-hover);
--color-primary-muted: var(--primary-muted);
--color-accent: var(--accent);
/* Semantic status colors */
--color-success: var(--success);
--color-warning: var(--warning);
--color-error: var(--error);
--color-info: var(--info);
/* Visualization pointer colors */
--color-viz-pointer-left: var(--viz-pointer-left);
--color-viz-pointer-right: var(--viz-pointer-right);
--color-viz-pointer-mid: var(--viz-pointer-mid);
--color-viz-pointer-default: var(--viz-pointer-default);
--color-viz-success: var(--viz-success);
--color-viz-compare: var(--viz-compare);
--color-viz-highlight: var(--viz-highlight);
--font-sans: var(--font-inter);
--font-mono: var(--font-jetbrains-mono);
}
:root {
--background: #ffffff;
--background-subtle: #f5f5f5;
--foreground: #171717;
--foreground-muted: #5a5a5a;
--surface: #ffffff;
--surface-variant: #f5f5f5;
--surface-subtle: #fafafa;
--card: #ffffff;
--card-foreground: #171717;
--primary: #3b82f6;
--primary-foreground: #ffffff;
--primary-hover: #2563eb;
--primary-muted: #dbeafe;
--secondary: #f3f4f6;
--secondary-foreground: #171717;
--muted: #f3f4f6;
--muted-foreground: #5f6368;
--accent: #0891b2;
--border: #e5e7eb;
--border-focus: var(--primary);
--border-disabled: #d4d4d4;
--ring: #3b82f6;
/* Semantic status colors */
--success: #059669;
--warning: #d97706;
--error: #dc2626;
--info: #2563eb;
/* Difficulty colors */
--difficulty-easy: #16a34a;
--difficulty-easy-bg: #dcfce7;
@@ -70,23 +122,54 @@
--viz-visited: #9ca3af;
--viz-swapping: #8b5cf6;
--viz-transition: 300ms;
/* Visualization pointer colors */
--viz-pointer-left: #2563eb;
--viz-pointer-right: #ea580c;
--viz-pointer-mid: #9333ea;
--viz-pointer-default: #4b5563;
--viz-success: #16a34a;
--viz-compare: #eab308;
--viz-highlight: #4f46e5;
--viz-dimmed-opacity: 0.3;
/* Visualization timing */
--viz-duration-fast: 200ms;
--viz-duration-normal: 400ms;
--viz-duration-slow: 600ms;
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
--background-subtle: #121212;
--foreground: #e5e5e5;
--foreground-muted: #b0b0b0;
--surface: #141414;
--surface-variant: #1e1e1e;
--surface-subtle: #0f0f0f;
--card: #171717;
--card-foreground: #ededed;
--primary: #3b82f6;
--primary: #6366f1;
--primary-foreground: #ffffff;
--primary-hover: #818cf8;
--primary-muted: #1e1b4b;
--secondary: #262626;
--secondary-foreground: #ededed;
--muted: #262626;
--muted-foreground: #a3a3a3;
--accent: #22d3ee;
--border: #262626;
--border-focus: var(--primary);
--border-disabled: #404040;
--ring: #3b82f6;
/* Semantic status colors */
--success: #10b981;
--warning: #f59e0b;
--error: #ef4444;
--info: #3b82f6;
/* Difficulty colors (dark mode) */
--difficulty-easy: #4ade80;
--difficulty-easy-bg: rgba(34, 197, 94, 0.2);
@@ -142,6 +225,21 @@
--viz-found: #22c55e;
--viz-visited: #6b7280;
--viz-swapping: #8b5cf6;
/* Visualization pointer colors (dark mode) */
--viz-pointer-left: #3b82f6;
--viz-pointer-right: #f97316;
--viz-pointer-mid: #a855f7;
--viz-pointer-default: #6b7280;
--viz-success: #22c55e;
--viz-compare: #fbbf24;
--viz-highlight: #6366f1;
--viz-dimmed-opacity: 0.3;
/* Visualization timing */
--viz-duration-fast: 200ms;
--viz-duration-normal: 400ms;
--viz-duration-slow: 600ms;
}
}

View File

@@ -14,8 +14,11 @@ import {
RelatedPatterns,
} from "@/components/patterns";
import { PatternVisualization } from "@/components/visualization";
import { TwoPointersVisualization } from "@/components/visualizations-new";
import { TwoPointersVisualization, PrefixSumVisualization } from "@/components/visualizations-new";
import { twoSumAlgorithm } from "@/content/algorithms/two-sum";
import { slidingWindowAlgorithm } from "@/content/algorithms/sliding-window";
import { binarySearchAlgorithm } from "@/content/algorithms/binary-search";
import { prefixSumAlgorithm } from "@/content/algorithms/prefix-sum";
interface PageProps {
params: Promise<{ slug: string }>;
@@ -109,14 +112,13 @@ export default async function PatternDetailPage({ params }: PageProps) {
{/* Interactive Visualization */}
{slug === "two-pointers" ? (
<Card>
<CardHeader>
<CardTitle>Interactive Visualization</CardTitle>
</CardHeader>
<CardContent>
<TwoPointersVisualization algorithm={twoSumAlgorithm} />
</CardContent>
</Card>
<TwoPointersVisualization algorithm={twoSumAlgorithm} />
) : slug === "sliding-window" ? (
<TwoPointersVisualization algorithm={slidingWindowAlgorithm} />
) : slug === "binary-search" ? (
<TwoPointersVisualization algorithm={binarySearchAlgorithm} />
) : slug === "prefix-sum" ? (
<PrefixSumVisualization algorithm={prefixSumAlgorithm} />
) : pattern.visualization_examples && pattern.visualization_examples.length > 0 ? (
<Card>
<CardHeader>