I've built the FY2024 to FY2025 customer revenue walk and a one-page note for the board call. The script checked that the walk adds up to the cent before writing any figures. Revenue was flat: **FY2025 was $11,238K against $11,243K in FY2024, a change of ($5K), or (0.04%).**

| Step | Amount | Customers |
| --- | --- | --- |
| FY2024 | $11,243K | |
| Timing | $53K | 3 |
| Churned (Loss) | ($1,288K) | 4 |
| Contraction (Decline) | ($443K) | 11 |
| Expansion (Upsell) | $1,211K | 23 |
| New logos (New) | $463K | 6 |
| FY2025 | $11,238K | |

**What the board will want to hear:**
- **Churn is concentrated.** Fenwick Legal lost ($686K) and Birchway Foods lost ($503K). Those two accounts make up most of the ($1,288K) lost.
- **Expansion and new logos made up the gap.** Upsell across 23 customers added $1,211K. Harbor Freight Partners added the most, $148K. Six new logos added $463K, led by Thistle Gardens at $116K.
- **Contraction was spread out.** Driftwood Media fell ($113K) and Juniper Schools fell ($107K). The remaining decline came from smaller amounts across the other 9 contracting customers.

**Things to know before the call:**
- **There is a Timing row.** It holds $53K from 3 customers whose renewal dates moved, so that revenue isn't real growth. Each customer was classed as churned, contracted, expanded or new after taking timing out.
- **The note uses different names.** It calls your categories Loss, Decline, Upsell and New. They are the same four movements.
- **The rows don't add exactly.** Each amount is rounded to $K on its own, so the rows don't sum to the FY2025 total. The note says so in its data notes.
- **The data doesn't explain causes.** It doesn't say why Fenwick Legal and Birchway Foods left. If the board asks, the answer has to come from the account teams or CRM churn reasons.

I didn't make a waterfall chart. The table above has the steps; I can build the chart if you need a slide.

Files are in `output/`:
- `bridge-note.md`
- `bridge.json`