Skip to content

2 cases built from this template

Same prompt, different [VARIABLES]. Click one to preview it above.

About this template

This is a single long-scroll page that teaches compound interest by letting the reader play with it. The first screen is the tool itself: three sliders for monthly deposit, annual rate and years sit beside a large stacked area chart that splits the balance into what you put in and what interest added. A balance counter tweens as you drag, a crosshair reads out any year, and a marker shows the year interest overtakes your deposits.

Below the tool, the page slows down into short scrollytelling chapters. A sticky chart changes with each step while a paragraph explains one idea at a time: interest on deposits, interest on interest, the bend in the curve, and why time matters more than amount. A comparison scene plays two savers who put away the same monthly sum but start ten years apart, then spells out the gap at 65 in plain numbers. An inflation switch turns every figure on the page into today's money, and a formula corner substitutes the live slider values into the math, with a compounding-frequency control and a year-by-year table.

The look is a quiet editorial explainer: warm off-white paper, deep ink text, a slate layer for deposits, a green layer for interest and a coral accent reserved for inflation. Headings use a soft serif, the interface uses a clean sans, and every number is set in tabular mono so columns never shift. Four gouache illustrations give the chapters a printed feel. A disclaimer band states that all figures are illustrative.

It suits personal finance writers, teachers and newsletter authors. To adapt it, change the brand, audience, currency, default deposit and the two starting ages, or keep the skeleton of controls, live chart, comparison scene and reframing toggle and point it at loans, savings goals or subscriptions.

The template prompt

The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].

# Compound Interest Interactive Explainer

Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.

## Brief
A single-page interactive explainer published by [BRAND] that teaches compound interest to [AUDIENCE]. The hero is a working calculator: sliders for monthly deposit, annual rate and years drive a large hand-drawn SVG stacked area chart (deposits vs. interest) and an animated final-balance counter. Below it, scrollytelling chapters with a sticky chart explain compounding step by step, a 'start at [START_AGES]' scene compares two savers, an inflation toggle reframes every figure in today's money, and a formula corner shows the math with live values. Every figure is a labeled hypothetical; the page never gives advice.

- Audience: [AUDIENCE]: curious beginners who have heard 'start early' but never seen why, plus teachers and writers who want to link to a clear, playable explanation.
- Goal: The reader drags a slider within five seconds of landing, understands that interest on interest makes the curve bend upward, and leaves able to explain in one sentence why starting ten years earlier matters more than depositing a bit more. No sign-up, no lead capture.
- Tone: Calm, warm and precise, like a well-edited magazine explainer. Short sentences, concrete numbers, second person used only to describe what the chart shows ('your deposits', 'your balance'), never to tell the reader what to do. No hype, no urgency, no 'guaranteed', no 'you should'.

## Stack
- Framework: Vite 5 + React 18 + TypeScript
- Styling: Tailwind CSS 3.4
- Libraries: react, react-dom 18 (MIT), vite 5, @vitejs/plugin-react (MIT), typescript 5 (Apache-2.0), tailwindcss 3.4, postcss, autoprefixer (MIT), motion (motion.dev, import from motion/react) (MIT), d3-shape (area, line, curveMonotoneX) (ISC), d3-scale (scaleLinear) (ISC), lucide-react (ISC), @fontsource-variable/fraunces (OFL-1.1 font, MIT package), @fontsource-variable/public-sans (OFL-1.1 font, MIT package), @fontsource/ibm-plex-mono (OFL-1.1 font, MIT package)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
  - Scaffold with Vite's react-ts template; the single page is index.html at the project root mounting src/main.tsx.
  - vite.config.ts: base './', build.sourcemap false, build.outDir 'dist'. Do not copy src/ into dist/.
  - package.json scripts: dev = vite, build = tsc -b && vite build, preview = vite preview.
  - Import fonts once in src/main.tsx: '@fontsource-variable/fraunces', '@fontsource-variable/public-sans', '@fontsource/ibm-plex-mono/400.css', '@fontsource/ibm-plex-mono/500.css'.
  - tailwind.config.ts: extend colors with paper, paper2, card, ink, muted, rule, slate, green, greenDeep, coral, coralTint, amber using the hex values in Design; fontFamily display = ['Fraunces Variable', 'Georgia', 'serif'], sans = ['Public Sans Variable', 'system-ui', 'sans-serif'], mono = ['IBM Plex Mono', 'ui-monospace', 'monospace']; maxWidth page = '1240px'.
  - src/index.css: Tailwind layers, body bg paper and text ink, font-feature-settings 'tnum' 1 on every element with class .num, custom range-input styling (track 4px rule color, filled part green via a CSS variable --fill set inline, 22px round thumb in card color with a 2px ink border and a soft shadow, thumb scales to 1.1 on active, visible 2px green focus ring).
  - All copy, variable values, slider ranges, the hypothetical defaults and FAQ text live in one file: src/content.ts. When the variable values differ from the defaults, rewrite the copy in that file to fit them; components only read from it.
  - src/lib/finance.ts holds pure functions: simulate({ monthly, ratePct, years, perYear }) returns one row per year { year, deposits, interest, balance } using month-by-month simulation with deposits at the end of each month and periodic monthly rate i = (1 + r/n)^(n/12) - 1 where n is compounding periods per year (1, 4, 12 or 365); toReal(value, inflationPct, year) = value / (1 + inflationPct/100)^year; crossoverYear(rows) = first year where interest > deposits, or null.
  - src/lib/format.ts: one LOCALE constant 'en-US' and the CURRENCY from content.ts feed a single Intl.NumberFormat for currency (maximumFractionDigits 0), a compact formatter for axis labels ($100K style, notation 'compact'), and a percent formatter with one decimal. Every number on the page goes through these.
  - src/state.tsx: a React context holding monthly, ratePct, years, perYear (default 12), inflationOn (default false), inflationPct (default 2.5). Every chart and sentence on the page reads from this one store, so moving a hero slider updates every section.
  - src/hooks/useTweenedNumber.ts: wraps motion's animate() to tween a displayed number to its new target over 0.6s with ease [0.22, 1, 0.36, 1]; returns the target immediately when useReducedMotion() is true.
  - src/hooks/useActiveStep.ts: IntersectionObserver with rootMargin '-45% 0px -45% 0px' that returns the index of the scrollytelling step currently in the middle of the viewport.
  - Charts are hand-written SVG components in src/charts/ using d3-scale for scales and d3-shape area/line with curveMonotoneX for paths. Each chart is responsive via a ResizeObserver on its wrapper, with a viewBox that matches the measured width.
  - Put the downloaded illustrations in public/images/ and reference them with relative paths (./images/...). Add ASSETS.md at the project root listing every image and font with path, source URL, author and license.
  - Favicon: public/favicon.svg, a 32px rounded square in green #2F8F5B with a white upward-bending curve stroke. Page <title>: '[BRAND] · How compound interest works'.

## Variables
- [BRAND] — Publisher name (default: "Tallypine"). The newsletter, school or blog publishing the explainer. Shown in the header, footer and page title.
- [AUDIENCE] — Who it is written for (default: "people in their twenties opening their first savings account"). Shapes the intro copy, examples and FAQ wording.
- [CURRENCY] — Currency (ISO 4217 code) (default: "USD"). Passed to Intl.NumberFormat with the en-US locale; every figure on the page uses it.
- [MONTHLY_DEPOSIT] — Default monthly deposit (default: "200"). Whole number in the chosen currency. Starting value of the deposit slider and the deposit used in the comparison scene.
- [START_AGES] — Two starting ages to compare (default: "25 and 35"). Earlier age first, ten years apart works best. Both savers stop at 65.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/compound-interest-interactive-explainer in the footer (default: yes; delete this line to remove it)

The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.

## Design
### Colors
- paper `#F6F1E7` — Page background, warm off-white
- paper2 `#EEE6D6` — Alternate section background and inset wells behind charts
- card `#FFFDF8` — Control panel, chart cards, FAQ items, slider thumbs
- ink `#1E2226` — Headings, body text, axis labels, crosshair line
- muted `#5B6168` — Secondary text, captions, tick labels
- rule `#D9CFBD` — Hairlines, gridlines, slider tracks, card borders
- slate `#6E7F91` — Principal / deposits layer in every chart, late-starter line
- green `#2F8F5B` — Interest layer, early-starter line, slider fill, links, primary buttons
- greenDeep `#1F6B42` — Hover state for green, text on light green tints
- coral `#E2684A` — Inflation only: today's-money mode badge, inflation slider fill, shrinking-basket accents
- coralTint `#F7DCD2` — Disclaimer band background (text in ink)
- amber `#D9A43B` — Crossover marker dot and its leader line, nothing else

### Typography
- Display headings (H1 64/68px desktop, 40/44px mobile; H2 44/50px desktop, 32/36px mobile), weight 400 with opsz auto and a slight negative tracking (-0.01em); italic 400 used for one emphasized phrase per heading: Fraunces Variable (OFL), weights 400/600
- UI and body text: body 18/30px, labels 14px weight 600 uppercase tracking 0.08em, buttons 15px weight 600: Public Sans Variable (OFL), weights 400/500/600
- All numbers: counter, slider readouts, tooltips, axis ticks, formula, table. Tabular figures always: IBM Plex Mono (OFL), weights 400/500

### Layout & motion
- Spacing: 8px base unit. Page container max-width 1240px with 24px side padding (16px under 640px). Sections are separated by 128px vertical padding on desktop, 80px on mobile. Text columns cap at 62ch. Cards use 28px inner padding (20px on mobile). 12-column grid with 32px gutters on desktop.
- Radius: Cards and chart wells 18px; sliders' tracks fully rounded; buttons and segmented controls 999px pill; tooltips 10px; illustrations 14px with a 1px rule-colored border.
- Motion: Chart redraws: when any input changes, area and line paths morph to the new shape over 0.5s with ease [0.22, 1, 0.36, 1] (animate the path 'd' via motion's motion.path with the new d value, both paths always built from the same number of points so they interpolate cleanly); during an active slider drag, update instantly without tweening to keep it responsive.
- Motion: Numbers never jump: every currency figure uses useTweenedNumber (0.6s).
- Motion: Scroll reveals: section headings and paragraphs fade up 16px over 0.6s when 25% visible, once only, staggered 0.08s between siblings.
- Motion: Scrollytelling: the sticky chart crossfades layers and highlights over 0.45s when the active step changes; inactive step paragraphs drop to 35% opacity.
- Motion: Comparison scene: a 'Play the decades' button animates an age scrubber from the earlier start age to 65 over 6s (linear), drawing both lines progressively via pathLength; the gap bracket at 65 grows in after the lines finish (0.6s spring, stiffness 160, damping 20).
- Motion: Micro-interactions: slider thumb scales to 1.1 while dragged; segmented controls slide a pill highlight between options with a motion layoutId; the inflation toggle swaps the mode badge text with a 0.25s vertical slide.
- Motion: prefers-reduced-motion: disable path morphing, tweening, reveals and the play animation (show the finished state with the scrubber at 65), keep only instant state changes and color transitions.
- Imagery: The first screen's visual anchor is the polished live chart card itself, not a photo. Supporting imagery is a set of four gouache-and-colored-pencil editorial illustrations on warm cream paper in the page's palette (slate blue, leaf green, soft coral, ink), generated for this template, one per chapter, shown at 4:3 inside 14px-rounded frames with a caption below in muted 14px text. Icons are Lucide at 18px with 1.75 stroke width. Everything else (charts, basket, brackets, markers) is drawn in SVG. No stock photos, no people's faces, no coins with real currency markings.

## Pages & Sections
### [BRAND] · How compound interest works (`index.html`)
1. **Header (shared, sticky)** — Left: Lucide Sprout icon in green inside a 32px card-colored circle with a rule border, then the wordmark '[BRAND]' in Fraunces 22px weight 600. Center (desktop only): anchor links 'The tool', 'Why time wins', '[START_AGES]', 'Inflation', 'The formula' (each label rewritten to fit; the comparison link reads 'Start at 25 vs 35' for the defaults), 15px weight 500, muted, ink on hover with a 2px green underline that grows from the left. Right: a compact segmented control 'Nominal | Today's money' bound to inflationOn (the same state as the hero toggle); when Today's money is active its pill is coral with white text. Mobile: wordmark left, the segmented control right, a Lucide Menu button that opens a full-width sheet with the anchor links.
   Layout: Full-width bar, 68px tall, background paper at 85% opacity with backdrop-blur 8px, 1px rule bottom border that appears only after scrolling 8px. Content inside the 1240px container.
   Motion: Border and shadow fade in on scroll. Mobile sheet slides down 0.3s.
2. **Disclaimer band** — Lucide Info icon, then: 'Illustrative only. Every rate on this page is a hypothetical example, not a forecast. This is not financial advice, and returns are not guaranteed.' Text 14px ink, the first two words weight 600.
   Layout: Directly under the header, full width, coralTint background, 44px tall on desktop (wraps to two lines on mobile), text centered in the container.
   Motion: None.
3. **Hero: the tool** — Left column: eyebrow 'An interactive explainer from [BRAND]' (14px uppercase label, green). H1 built from live values: 'Watch $200 a month quietly become *$398,298*.' where the deposit and the final balance come from state and tween (italic Fraunces on the balance, colored green). Subhead (18px muted, 2 lines): 'Drag the sliders. The slate layer is money you put in; the green layer is interest, and interest on that interest. Every number on this page updates with you.' Below it, the control card with three sliders, each a row of label (14px uppercase), live readout in mono 20px right-aligned, and the range input: 'Monthly deposit' 0 to 2,000 step 25, default [MONTHLY_DEPOSIT]; 'Annual rate (hypothetical)' 0 to 12% step 0.1, default 6.0%; 'Years' 1 to 50 step 1, default 40. Under the sliders, a row with the inflation switch: a toggle labeled 'Show in today's money' plus, when on, an inline 'Inflation' mini slider 0 to 6% step 0.1 (default 2.5%) with coral fill. Right column: the chart card. Top of the card: label 'Balance after 40 years' (years live) and the big counter in mono 56px weight 500 ink, tweening; beneath it three stat chips in a row: 'Deposited $96,000' (slate dot), 'Interest earned $302,298' (green dot), 'Interest share 76%' (mono). When inflation is on, a coral badge 'In today's money at 2.5% inflation' appears above the counter and all values switch to real terms (the default balance reads $148,338). The chart: stacked area with deposits at the bottom (slate fill at 0.9 opacity) and interest on top (green fill at 0.9), x axis in years (ticks every 5 or 10 depending on range), y axis with compact currency ticks and dashed rule gridlines, no chart border. Hover or touch-drag shows a vertical ink crosshair, dots on both layer tops, and a tooltip card: 'Year 22', 'Deposited $52,800', 'Interest $56,445', 'Balance $109,245'. An amber dot with a thin leader line marks the crossover year with the annotation 'Year 22: interest passes your deposits' (hidden with a muted note 'Interest does not overtake deposits in this range' when crossoverYear is null). Below the chart: legend (slate square 'Your deposits', green square 'Interest') and a link 'See how it works ↓' to the next section.
   Layout: Container grid, 12 columns: text and control card span 5 columns, chart card spans 7, top-aligned, 48px gap. Chart card is card-colored with a 1px rule border, 18px radius, soft shadow 0 20px 40px -24px rgba(30,34,38,0.25); chart height 420px on desktop. Hero section has 72px top padding. Under 1024px the columns stack: heading and subhead first, then the chart card, then the control card, and the chart height drops to 300px. The whole hero, chart included, fits in 900px of viewport height on a 1440 desktop.
   Motion: On load the H1 words fade up in sequence (0.05s stagger), then the areas draw from left to right with a clip-path reveal over 1.2s and the counter counts up from 0. On slider change, paths morph and numbers tween as described in Design motion. The crossover marker slides along the x axis to its new year with a 0.4s spring.
4. **Chapter 1: What compounding is (scrollytelling)** — Section eyebrow 'Chapter 1' and H2 'Interest that earns *its own* interest.' A short lede paragraph and the illustration compounding-seedling.webp above the steps. Four steps, each a card with a mono step number and 2 to 3 sentences, with numbers from the live state: Step 1 'Year one': 'You deposit $2,400 over twelve months. At 6.0%, they earn about $67 in interest. Small, and almost all of the bar is slate.' Step 2 'Interest on interest': 'In year two, that $67 starts earning too. The green layer now grows from two sources: your new deposits and the interest already sitting there.' Step 3 'The bend': 'By year 22 the green layer is taller than the slate one. From here, interest adds more each year than you do.' Step 4 'The snowball': 'In the last ten years alone the balance grows by about $197,000, more than double everything you deposited in forty years.' (compute the last-ten-years growth and the ratio from state). The sticky chart shows yearly bars (one bar per year, slate base, green top) and changes per step: step 1 only year 1 visible and zoomed; step 2 the first five years with the green tops highlighted and the rest of each bar faded; step 3 all years with bars after the crossover year in full color, earlier ones at 40% and the amber crossover marker; step 4 all years with the last ten years highlighted and a bracket labeled with their combined growth.
   Layout: paper2 section background. Two columns on desktop: left 5 columns hold the illustration (4:3, 14px radius) and then the four step cards spaced 60vh apart; right 7 columns hold a sticky chart card (top: 120px, height 70vh max 560px). On mobile the chart becomes sticky at the top (height 44vh) and the step cards scroll over it on a card background with 90% opacity.
   Motion: useActiveStep picks the active step; bars animate height and opacity over 0.45s on step change; inactive steps at 35% opacity.
5. **Chapter 2: Why time beats amount** — Eyebrow 'Chapter 2', H2 'Double the time, not *the deposit*.' Lede: 'Two ways to put away the same $96,000. One saves twice as much for half as long. The other saves the regular amount for twice as long.' (totals computed from state). Two side-by-side scenario cards with a horizontal stacked bar each (slate deposits, green interest), drawn on the same scale: Card A 'Double the deposit': '$400 a month for 20 years' → '$184,816'; Card B 'Double the years': '$200 a month for 40 years' → '$398,298'. Under them, a one-line conclusion in Fraunces italic 24px: 'Same money in. More than twice the money out, because the green layer had twenty more years to grow.' Card A uses 2 × deposit and half the slider's years (rounded down); Card B uses the slider's deposit and years. To the right of the cards on desktop, the illustration time-hourglass.webp with caption 'Time does the heavy lifting.'
   Layout: paper background. Desktop: cards in a 2-column grid spanning 8 columns, illustration in the remaining 4 columns, vertically centered. Mobile: illustration first, then cards stacked.
   Motion: Bars grow from width 0 to their value over 0.9s when the cards scroll into view, Card B starting 0.3s after Card A; values tween.
6. **Chapter 3: Start at 25 vs 35** — Eyebrow 'Chapter 3', H2 'Same deposit. *Ten years* apart.' Lede introducing two invented savers: 'Maya starts putting $200 a month away at 25. Theo starts the same $200 a month at 35. Both stop at 65, both at the same hypothetical 6.0%.' The chart: x axis age from the earlier start age to 65, y axis balance; two lines with soft area fills under them, green for Maya (early) and slate for Theo (late); end labels at 65 with names and balances: 'Maya $398,298', 'Theo $200,903'. A vertical bracket at age 65 between the two end points labeled 'Gap $197,395'. A 'Play the decades' button (green pill, Lucide Play icon) animates an age scrubber and a live readout 'Age 47: Maya $… · Theo $…'. Three stat cards below the chart: 'Maya deposited $96,000', 'Theo deposited $72,000', 'Maya put in $24,000 more and ends with $197,395 more.' Then the illustration two-paths.webp beside a closing paragraph: 'The ten years Theo missed were not just ten years of deposits. They were the first ten years of compounding, the ones every later dollar would have been built on.' Ages come from [START_AGES]; the deposit and rate come from the shared state; the savers' names stay Maya and Theo unless the copy is rewritten.
   Layout: paper2 background. Chart card spans the full container width, 460px tall on desktop (320px mobile), controls (play button and readout) in a row above the chart. Stat cards in a 3-column grid (stacked on mobile). Closing row: illustration 5 columns, paragraph 7 columns.
   Motion: Lines draw on first view (pathLength 0 to 1 over 1.4s, Theo's line starts when the x axis reaches his start age). Play button behavior as in Design motion; pressing it again restarts. Bracket grows in after the lines finish.
7. **Chapter 4: Inflation** — Eyebrow 'Chapter 4', H2 'A big number is not *the same* as big buying power.' Lede: 'Prices tend to rise over time, so a balance forty years from now buys less than the same figure would today. Switch to today's money to see every number on this page adjusted by a hypothetical inflation rate.' A large toggle card repeats the global switch ('Nominal' / 'Today's money') with the inflation slider (0 to 6%, default 2.5%, coral fill). Next to it, an SVG 'basket' visual: a simple drawn grocery basket filled with 10 rounded item shapes in green, slate and coral; the number of filled items shrinks to match purchasing power of 100 units of currency after the selected years (at 2.5% for 40 years: '$100 today buys what $37 buys in year 40', so about 4 of 10 items remain, the rest become dashed outlines). Two figures side by side in mono 40px: 'Nominal balance $398,298' and 'In today's money $148,338' with a coral arrow between them. Illustration inflation-basket.webp with caption 'The same basket, a different price.'
   Layout: paper background. Desktop: toggle card and basket visual in a 2-column row (6 + 6), then the two big figures centered beneath with the illustration to the right (figures 7 columns, illustration 5). Mobile: stacked in that order.
   Motion: Basket items pop out (scale 1 to 0.6, fade to an outline) one by one with 0.05s stagger when the value changes; big figures tween. Turning the toggle on tints the whole page's chart green layers 10% toward coral for 0.3s as a visual cue, then settles.
8. **The formula corner** — Eyebrow 'Under the hood', H2 'The math, *with your numbers*.' A plain-language explanation in three short lines: 'Each month your balance grows by a small rate, then your deposit is added. Repeat for every month. The formula below does all of those months at once.' A formula card in mono: line 1 'i = (1 + r / n)^(n / 12) − 1', line 2 'Balance = PMT × ((1 + i)^(12 × t) − 1) / i', and under each a substituted line with live values in green, e.g. 'i = (1 + 0.06 / 12)^(12 / 12) − 1 = 0.005000', 'Balance = 200 × ((1.005000)^480 − 1) / 0.005000 = $398,298'. A key list explains PMT (monthly deposit), r (annual rate as a decimal), n (compounding periods per year), t (years). A segmented control 'Compounding: Yearly | Quarterly | Monthly | Daily' (n = 1, 4, 12, 365; default Monthly) updates the formula and the whole page. A small comparison table 'How much frequency matters' lists all four frequencies with the current inputs: Yearly $381,536, Quarterly $395,098, Monthly $398,298, Daily $399,872, with the selected row highlighted and a note: 'Frequency moves the result a little. Time moves it a lot.' Below, a disclosure button 'Show the year-by-year table' (Lucide ChevronDown) that expands a scrollable table (max-height 420px, sticky header) with columns Year, Deposited, Interest, Balance (and Balance in today's money when inflation is on), mono tabular numbers, zebra rows in paper2.
   Layout: paper2 background. Desktop: explanation and key list in 5 columns, formula card plus frequency control and comparison table in 7 columns. The year table spans full width below. Mobile: stacked; formula lines wrap at operators and the table scrolls horizontally inside its card.
   Motion: Substituted values crossfade when they change (0.25s). Table expands with height animation 0.35s.
9. **Questions** — H2 'Fair questions'. Five accordion items (Lucide Plus rotating to an X): 1 'Is 6% a realistic rate?' 'It is a round, hypothetical number chosen to make the shape of the curve easy to see. Real returns vary year to year, can be negative, and are never guaranteed. Try 3% or 9% with the slider to see how much the rate changes the outcome.' 2 'Why does the chart assume the same deposit every month?' 'To isolate one idea: what time and compounding do on their own. Real life has raises, gaps and withdrawals, which this explainer leaves out on purpose.' 3 'What about taxes and fees?' 'They are not included. Any yearly fee or tax works like a lower rate, so you can approximate it by moving the rate slider down.' 4 'Does this page tell me what to invest in?' 'No. [BRAND] explains how the math works. It does not recommend any account, product or strategy, and it does not know your situation.' 5 'Why switch to today's money?' 'Because a balance decades away is measured in future prices. Adjusting for a hypothetical inflation rate makes it easier to compare with what money buys now.'
   Layout: paper background. Narrow centered column, max-width 760px, items are card-colored rows with 1px rule borders, 18px radius, 24px padding, 12px gap.
   Motion: Accordion height animation 0.3s, one item open at a time.
10. **Footer (shared)** — Top: the disclaimer repeated in a coralTint panel: 'All figures are illustrative and based on hypothetical rates. Nothing on this page is financial advice, and past or projected returns are not guaranteed.' Then a three-column row: left, the Sprout mark and '[BRAND]' with the line 'A free weekly letter about money basics for [AUDIENCE].'; middle, 'About the numbers': 'Deposits are added at the end of each month. Interest compounds at the frequency you choose. Inflation adjusts each year's balance back to today's prices.'; right, anchor links back to each chapter. Bottom row: '© [BRAND]' at left and the optional [CREDIT] link at right, 13px muted.
   Layout: ink background (#1E2226) with paper-colored text and muted links at 70% opacity; the coralTint disclaimer panel sits at the top inside the container with ink text. 80px top padding, 40px bottom. Columns stack on mobile.
   Motion: None.

## Assets
- image: https://media.vibefather.ai/assets/a3fd809f-38a4-47be-91b5-cabdd47e6177/compounding-seedling.webp → public/images/compounding-seedling.webp. Alt: 'A small green seedling growing out of a glass jar half filled with plain coins, painted in gouache on cream paper.' Used at the top of Chapter 1. Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template.
- image: https://media.vibefather.ai/assets/a3fd809f-38a4-47be-91b5-cabdd47e6177/time-hourglass.webp → public/images/time-hourglass.webp. Alt: 'An hourglass whose falling sand turns into green leaves gathering in the lower bulb.' Used beside the scenario cards in Chapter 2. Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template.
- image: https://media.vibefather.ai/assets/a3fd809f-38a4-47be-91b5-cabdd47e6177/two-paths.webp → public/images/two-paths.webp. Alt: 'Two winding paths of different lengths climbing a gentle hill toward the same large tree at the top.' Used in the closing row of Chapter 3. Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template.
- image: https://media.vibefather.ai/assets/a3fd809f-38a4-47be-91b5-cabdd47e6177/inflation-basket.webp → public/images/inflation-basket.webp. Alt: 'A woven market basket holding a loaf of bread and a few apples beside a short stack of plain coins.' Used in Chapter 4. Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template.
- image: Everything else is drawn in code: all charts (stacked area, yearly bars, scenario bars, comparison lines), the crossover marker, gap bracket, grocery basket visual and favicon are hand-written SVG. No chart library, no placeholder-image services.
- icon: lucide-react (ISC): Sprout, Info, Menu, X, Play, RotateCcw, ChevronDown, Plus, ArrowRight, ArrowDown. 18px, strokeWidth 1.75, currentColor.
- font: Self-hosted via Fontsource npm packages: @fontsource-variable/fraunces, @fontsource-variable/public-sans, @fontsource/ibm-plex-mono (weights 400 and 500). All OFL-1.1. List them in ASSETS.md.

## Don'ts
- No backend of any kind: no server code, API routes, databases, auth, analytics or third-party APIs. No forms that submit anywhere, no email capture, no sign-up, no 'talk to an advisor' or lead flow.
- No CDN script or link tags. Fonts are self-hosted through Fontsource only; never load fonts.googleapis.com, fonts.gstatic.com, Adobe Fonts or chart scripts from a CDN. No commercial fonts.
- No chart library (no Recharts, Chart.js, ECharts, Nivo, Highcharts). Charts are hand-written SVG with d3-shape and d3-scale only.
- No code or visuals copied from existing calculator sites or from restricted UI libraries (Aceternity UI, Tailwind Plus / Tailwind UI); recreate every effect from scratch.
- No real bank, brokerage, fund, fintech or app names, logos, products, index funds or tickers anywhere, including sample data and FAQ.
- No claims about real historical market returns or real-world rates presented as fact. All rates are labeled hypothetical, and the disclaimer appears both under the header and in the footer.
- No advice language: never 'you should invest', 'guaranteed', 'best investment', 'risk-free' or similar.
- No real people's names, likenesses or quotes, including famous investors and the compound-interest quote often misattributed to Einstein. The two savers are invented.
- No source maps in the production build and no src/ copied into dist/. Static output in dist/ from npm run build, with base './' so all asset paths are relative.
- Internal links are in-page anchors (#tool, #time, #compare, #inflation, #formula) or point to ./index.html, never to a bare directory.
- Never hotlink images: download every listed file into public/images/ and list each image and font in ASSETS.md with path, source URL, author and license.
- Keep dist/ under 20 MB. Zero console errors at 1440×900 and 390×844; no horizontal scroll on mobile.
- Respect prefers-reduced-motion as described in Design motion.
- Do not hard-code figures in copy: every number in headings, steps, captions and the formula is computed from the shared state, so it stays correct when sliders or variables change.
- No mention of VibeFather inside the site except the optional [CREDIT] link in the footer. All copy, labels, sample data and alt text in US English.

---
— Prompt by VibeFather · https://vibefather.ai/t/compound-interest-interactive-explainer · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown

Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.

DESIGN.md

The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.

---
name: "Compound Interest Interactive Explainer"
colors:
  paper: "#F6F1E7"
  paper2: "#EEE6D6"
  card: "#FFFDF8"
  ink: "#1E2226"
  muted: "#5B6168"
  rule: "#D9CFBD"
  slate: "#6E7F91"
  green: "#2F8F5B"
  greendeep: "#1F6B42"
  coral: "#E2684A"
  coraltint: "#F7DCD2"
  amber: "#D9A43B"
typography:
  display_headings_h1_64_68px_desktop_40_44px_mobile_h2_44_50px_desktop_32_36px_mobile_weight_400_with_opsz_auto_and_a_slight_negative_tracking_0_01em_italic_400_used_for_one_emphasized_phrase_per_heading: { family: "Fraunces Variable", weights: [400, 600] }
  ui_and_body_text_body_18_30px_labels_14px_weight_600_uppercase_tracking_0_08em_buttons_15px_weight_600: { family: "Public Sans Variable", weights: [400, 500, 600] }
  all_numbers_counter_slider_readouts_tooltips_axis_ticks_formula_table_tabular_figures_always: { family: "IBM Plex Mono", weights: [400, 500] }
spacing: "8px base unit. Page container max-width 1240px with 24px side padding (16px under 640px). Sections are separated by 128px vertical padding on desktop, 80px on mobile. Text columns cap at 62ch. Cards use 28px inner padding (20px on mobile). 12-column grid with 32px gutters on desktop."
radius: "Cards and chart wells 18px; sliders' tracks fully rounded; buttons and segmented controls 999px pill; tooltips 10px; illustrations 14px with a 1px rule-colored border."
---

# Compound Interest Interactive Explainer — Design System

Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.

## Colors
- **paper** `#F6F1E7` — Page background, warm off-white
- **paper2** `#EEE6D6` — Alternate section background and inset wells behind charts
- **card** `#FFFDF8` — Control panel, chart cards, FAQ items, slider thumbs
- **ink** `#1E2226` — Headings, body text, axis labels, crosshair line
- **muted** `#5B6168` — Secondary text, captions, tick labels
- **rule** `#D9CFBD` — Hairlines, gridlines, slider tracks, card borders
- **slate** `#6E7F91` — Principal / deposits layer in every chart, late-starter line
- **green** `#2F8F5B` — Interest layer, early-starter line, slider fill, links, primary buttons
- **greenDeep** `#1F6B42` — Hover state for green, text on light green tints
- **coral** `#E2684A` — Inflation only: today's-money mode badge, inflation slider fill, shrinking-basket accents
- **coralTint** `#F7DCD2` — Disclaimer band background (text in ink)
- **amber** `#D9A43B` — Crossover marker dot and its leader line, nothing else

## Typography
- **Display headings (H1 64/68px desktop, 40/44px mobile; H2 44/50px desktop, 32/36px mobile), weight 400 with opsz auto and a slight negative tracking (-0.01em); italic 400 used for one emphasized phrase per heading** — Fraunces Variable (OFL), weights 400/600. Self-host the font files.
- **UI and body text: body 18/30px, labels 14px weight 600 uppercase tracking 0.08em, buttons 15px weight 600** — Public Sans Variable (OFL), weights 400/500/600. Self-host the font files.
- **All numbers: counter, slider readouts, tooltips, axis ticks, formula, table. Tabular figures always** — IBM Plex Mono (OFL), weights 400/500. Self-host the font files.

## Spacing & shape
- Spacing: 8px base unit. Page container max-width 1240px with 24px side padding (16px under 640px). Sections are separated by 128px vertical padding on desktop, 80px on mobile. Text columns cap at 62ch. Cards use 28px inner padding (20px on mobile). 12-column grid with 32px gutters on desktop.
- Radius: Cards and chart wells 18px; sliders' tracks fully rounded; buttons and segmented controls 999px pill; tooltips 10px; illustrations 14px with a 1px rule-colored border.

## Motion
- Chart redraws: when any input changes, area and line paths morph to the new shape over 0.5s with ease [0.22, 1, 0.36, 1] (animate the path 'd' via motion's motion.path with the new d value, both paths always built from the same number of points so they interpolate cleanly); during an active slider drag, update instantly without tweening to keep it responsive.
- Numbers never jump: every currency figure uses useTweenedNumber (0.6s).
- Scroll reveals: section headings and paragraphs fade up 16px over 0.6s when 25% visible, once only, staggered 0.08s between siblings.
- Scrollytelling: the sticky chart crossfades layers and highlights over 0.45s when the active step changes; inactive step paragraphs drop to 35% opacity.
- Comparison scene: a 'Play the decades' button animates an age scrubber from the earlier start age to 65 over 6s (linear), drawing both lines progressively via pathLength; the gap bracket at 65 grows in after the lines finish (0.6s spring, stiffness 160, damping 20).
- Micro-interactions: slider thumb scales to 1.1 while dragged; segmented controls slide a pill highlight between options with a motion layoutId; the inflation toggle swaps the mode badge text with a 0.25s vertical slide.
- prefers-reduced-motion: disable path morphing, tweening, reveals and the play animation (show the finished state with the scrubber at 65), keep only instant state changes and color transitions.

## Imagery
The first screen's visual anchor is the polished live chart card itself, not a photo. Supporting imagery is a set of four gouache-and-colored-pencil editorial illustrations on warm cream paper in the page's palette (slate blue, leaf green, soft coral, ink), generated for this template, one per chapter, shown at 4:3 inside 14px-rounded frames with a caption below in muted 14px text. Icons are Lucide at 18px with 1.75 stroke width. Everything else (charts, basket, brackets, markers) is drawn in SVG. No stock photos, no people's faces, no coins with real currency markings.

## Tone
Calm, warm and precise, like a well-edited magazine explainer. Short sentences, concrete numbers, second person used only to describe what the chart shows ('your deposits', 'your balance'), never to tell the reader what to do. No hype, no urgency, no 'guaranteed', no 'you should'.

---
— Prompt by VibeFather · https://vibefather.ai/t/compound-interest-interactive-explainer · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown