- Cards (featured + gallery): hover adds -translate-y-1 + shadow-lg for subtle lift-off-surface effect - Homepage sections: replace hard border-b with gradient-fade dividers that taper to transparent at edges - Resistor button section: tighten vertical padding (py-10 → py-6) - Notebook editor: cell spacing increased (space-y-0 → space-y-3), add-cell button slides up on hover instead of abrupt opacity flash, status bar gets more breathing room and lighter text
90 lines
3.3 KiB
Plaintext
90 lines
3.3 KiB
Plaintext
---
|
|
import { rcLowPassSvg, astable555Svg, commonEmitterSvg } from '../lib/featured-waveforms';
|
|
|
|
const featured = [
|
|
{
|
|
id: 'rc-lowpass-filter',
|
|
title: 'RC Low-Pass Filter',
|
|
engine: 'ngspice' as const,
|
|
description: 'Classic transient analysis — square wave input through an RC network produces the characteristic exponential charge/discharge response.',
|
|
tags: ['transient', 'passive', 'beginner'],
|
|
svg: rcLowPassSvg,
|
|
},
|
|
{
|
|
id: '555-astable-blinker',
|
|
title: '555 Astable LED Blinker',
|
|
engine: 'ngspice' as const,
|
|
description: 'Timer IC in free-running mode — the capacitor ramp between comparator thresholds generates a square wave output.',
|
|
tags: ['timer', 'oscillator', 'digital'],
|
|
svg: astable555Svg,
|
|
},
|
|
{
|
|
id: 'common-emitter-amplifier',
|
|
title: 'Common Emitter Amplifier',
|
|
engine: 'ngspice' as const,
|
|
description: 'Single-stage BJT amplifier with AC analysis — input sine wave is amplified and phase-inverted at the collector.',
|
|
tags: ['amplifier', 'ac-analysis', 'bjt'],
|
|
svg: commonEmitterSvg,
|
|
},
|
|
];
|
|
|
|
const engineColor: Record<string, { border: string; bg: string; text: string }> = {
|
|
ngspice: { border: 'border-blue-500/30', bg: 'bg-blue-500/10', text: 'text-blue-400' },
|
|
ltspice: { border: 'border-amber-500/30', bg: 'bg-amber-500/10', text: 'text-amber-400' },
|
|
};
|
|
---
|
|
|
|
<section class="max-w-6xl mx-auto px-6 py-16">
|
|
<p class="text-sm font-semibold tracking-widest text-blue-400 uppercase mb-2">Featured</p>
|
|
<h2 class="text-2xl font-bold text-slate-100 mb-8">Start with a classic circuit</h2>
|
|
|
|
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
{featured.map((nb) => {
|
|
const colors = engineColor[nb.engine] ?? engineColor.ngspice;
|
|
return (
|
|
<a
|
|
href={`/notebook/${nb.id}`}
|
|
class:list={[
|
|
'group block rounded-lg border bg-slate-900/50 overflow-hidden',
|
|
'hover:border-blue-500/40 hover:bg-slate-800/70',
|
|
'hover:-translate-y-1 hover:shadow-lg hover:shadow-black/25',
|
|
'transition-all duration-200',
|
|
'border-slate-800',
|
|
]}
|
|
>
|
|
{/* Waveform thumbnail */}
|
|
<div class="w-full h-[180px] bg-[#0a0a0a] border-b border-slate-800/60 overflow-hidden">
|
|
<Fragment set:html={nb.svg} />
|
|
</div>
|
|
|
|
<div class="p-5">
|
|
<div class="flex items-start justify-between mb-2">
|
|
<h3 class="text-base font-semibold text-slate-100 group-hover:text-blue-400 transition-colors line-clamp-1">
|
|
{nb.title}
|
|
</h3>
|
|
<span class:list={[
|
|
'shrink-0 ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium border',
|
|
colors.border, colors.bg, colors.text,
|
|
]}>
|
|
{nb.engine}
|
|
</span>
|
|
</div>
|
|
|
|
<p class="text-sm text-slate-400 leading-relaxed mb-3 line-clamp-2">
|
|
{nb.description}
|
|
</p>
|
|
|
|
<div class="flex flex-wrap gap-1.5">
|
|
{nb.tags.map((tag) => (
|
|
<span class="text-xs bg-slate-700/50 text-slate-400 px-2 py-0.5 rounded">
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</a>
|
|
);
|
|
})}
|
|
</div>
|
|
</section>
|