spicebook/frontend/src/components/PipelineStrip.astro
Ryan Malloy 43789bdf24 Homepage redesign: show-don't-tell with animated scope hero
Restructure the homepage to lead with visuals instead of text:

- Hero: split layout with animated Tektronix 465 oscilloscope showing
  RC step response (CSS+SVG, zero JS) that links to the notebook
- Pipeline strip: 3-step Write → Simulate → Visualize with code/terminal
  previews and inline waveform SVG
- Featured notebooks: 3 curated circuits (RC, 555, common emitter) with
  pre-rendered waveform thumbnails
- Gallery cards: decorative graticule header strip, color-coded by engine
- Footer: updated copy with clearer call to action

All new sections are server-rendered Astro components. Total new client
JavaScript: zero bytes.
2026-02-20 15:16:53 -07:00

164 lines
5.0 KiB
Plaintext

---
import { Icon } from 'astro-icon/components';
---
<section class="max-w-6xl mx-auto px-6 py-16">
<div class="grid gap-6 md:grid-cols-[1fr_auto_1fr_auto_1fr] items-start">
<!-- Step 1: Write -->
<div class="pipeline-step">
<span class="pipeline-number">01</span>
<h3 class="pipeline-title">Write</h3>
<div class="pipeline-preview">
<pre class="pipeline-code"><span class="text-slate-500">* RC Low-Pass Filter</span>
<span class="text-blue-400">V1</span> in 0 PULSE(0 5 0 1n 1n 0.5m 1m)
<span class="text-blue-400">R1</span> in out 10k
<span class="text-blue-400">C1</span> out 0 100n
<span class="text-emerald-400">.tran</span> 10u 5m</pre>
</div>
<p class="pipeline-desc">
SPICE netlists with syntax highlighting and autocomplete
</p>
</div>
<!-- Arrow 1→2 -->
<div class="pipeline-arrow">
<Icon name="lucide:arrow-right" class="w-5 h-5 text-slate-600 hidden md:block" />
<Icon name="lucide:chevron-down" class="w-5 h-5 text-slate-600 md:hidden" />
</div>
<!-- Step 2: Simulate -->
<div class="pipeline-step">
<span class="pipeline-number">02</span>
<h3 class="pipeline-title">Simulate</h3>
<div class="pipeline-preview">
<div class="pipeline-terminal">
<div class="flex items-center gap-2 mb-2">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-400"></span>
<span class="text-emerald-400 text-xs font-mono font-semibold">ngspice 43</span>
</div>
<div class="text-xs font-mono text-slate-500 space-y-0.5">
<p>Circuit: RC Low-Pass Filter</p>
<p>Doing transient analysis...</p>
<p>501 data points, 23ms</p>
</div>
<div class="flex items-center gap-1.5 mt-2">
<Icon name="lucide:check-circle-2" class="w-3.5 h-3.5 text-emerald-400" />
<span class="text-emerald-400 text-xs font-mono font-semibold">complete</span>
</div>
</div>
</div>
<p class="pipeline-desc">
Run ngspice simulations with one click
</p>
</div>
<!-- Arrow 2→3 -->
<div class="pipeline-arrow">
<Icon name="lucide:arrow-right" class="w-5 h-5 text-slate-600 hidden md:block" />
<Icon name="lucide:chevron-down" class="w-5 h-5 text-slate-600 md:hidden" />
</div>
<!-- Step 3: Visualize -->
<div class="pipeline-step">
<span class="pipeline-number">03</span>
<h3 class="pipeline-title">Visualize</h3>
<div class="pipeline-preview pipeline-waveform">
<svg viewBox="0 0 300 140" xmlns="http://www.w3.org/2000/svg" class="w-full h-full" preserveAspectRatio="none">
<!-- Faint grid -->
<defs>
<pattern id="ps-grid" width="30" height="17.5" patternUnits="userSpaceOnUse">
<line x1="30" y1="0" x2="30" y2="17.5" stroke="rgba(45,212,191,0.06)" stroke-width="0.5"/>
<line x1="0" y1="17.5" x2="30" y2="17.5" stroke="rgba(45,212,191,0.06)" stroke-width="0.5"/>
</pattern>
</defs>
<rect width="300" height="140" fill="#0a0a0a"/>
<rect width="300" height="140" fill="url(#ps-grid)"/>
<!-- Input square wave (dim) -->
<polyline fill="none" stroke="rgba(96,165,250,0.3)" stroke-width="1.2"
points="0,115 0,25 75,25 75,115 150,115 150,25 225,25 225,115 300,115"/>
<!-- RC response (bright teal) -->
<path fill="none" stroke="#2dd4bf" stroke-width="1.8" stroke-linecap="round"
d="M0,115 C19,50 38,30 75,27 C94,95 112,112 150,114 C169,50 188,30 225,27 C244,95 262,112 300,114"/>
</svg>
</div>
<p class="pipeline-desc">
Interactive waveforms + oscilloscope mode
</p>
</div>
</div>
</section>
<style>
.pipeline-step {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.pipeline-number {
font-family: var(--font-mono, ui-monospace, monospace);
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 0.12em;
color: var(--color-sb-accent, #2563eb);
text-transform: uppercase;
}
.pipeline-title {
font-size: 1.125rem;
font-weight: 700;
color: #f1f5f9;
letter-spacing: -0.01em;
}
.pipeline-preview {
border-radius: 0.5rem;
border: 1px solid #1e293b;
background: #0f172a;
overflow: hidden;
min-height: 140px;
}
.pipeline-code {
font-family: var(--font-mono, ui-monospace, monospace);
font-size: 0.75rem;
line-height: 1.6;
padding: 0.875rem 1rem;
margin: 0;
white-space: pre;
color: #e2e8f0;
overflow: hidden;
}
.pipeline-terminal {
padding: 0.875rem 1rem;
}
.pipeline-waveform {
padding: 0;
aspect-ratio: 300 / 140;
}
.pipeline-desc {
font-size: 0.875rem;
color: #94a3b8;
line-height: 1.5;
}
.pipeline-arrow {
display: flex;
align-items: center;
justify-content: center;
padding-top: 5rem;
}
@media (max-width: 767px) {
.pipeline-arrow {
padding-top: 0;
padding-bottom: 0;
}
}
</style>