pristine
All examples

Persuade · Ledgerline

Pricing page

A pricing page that went from five plans, a fake countdown and costs hidden in 10px gray to three plans that price your actual setup: set how many bank accounts you'll connect and every card shows its real total.

Persona
Priya Raman, Freelance product designer
Their goal
Pick the cheapest plan that does her quarterly taxes, and know exactly what she'll pay, what happens after the trial and how to leave.
Lenses applied
delight, clarify, quieter, harden, animate, distill, adapt, colorize
/pristine polish src/pages/pricing.astro

Full pages. Scroll either one; they move together.

Before3.0/10

Pricing page before Pristine

After9.5/10

Pricing page after Pristine

Verdict

3.0/10 Level 2

Stock Bootstrap: tidy and readable, but pushy and evasive underneath. A countdown that resets daily, five identical cards with #0d6efd on nearly every button so nothing leads, a guilt-trip decline link, and the real costs (extra bank connections, the trial going read-only, cancelling via support) hidden in 10px #adb5bd fine print.

9.5/10 Level 10

"Price it for your setup": a stepper for bank accounts and a CPA toggle rewrite a receipt in every card ($12 Starter is really $21.98 with 3 accounts), a small chart shows where Business gets cheaper than Pro (9 accounts annual, 11 monthly), and the Best fit badge moves to match. Billing works with JS off, and trial, cancel and refund rules sit right under the plans.

Scores

Every Dimension, before and after.

Dimension scores out of 10
DimensionBeforeAfterChange
Persona fit310
Hierarchy & clarity310
Layout & spacing59
Typography59
Color & theming49
Consistency69
Responsiveness59
Motion & interaction39
Accessibility29
Copy210
Robustness & performance49

The critique

What the red pen found.

Vibe-code tells

  • Fake resetting countdown banner
  • Five tiers including Free and Enterprise
  • Stock Bootstrap look: every plan the same card, #0d6efd on every primary action
  • bg-warning "Most popular" badge on a blue-header card
  • Confirmshaming decline link
  • Hidden costs in 10px light-gray fine print
  • Colour-only ✓/✗ comparison cells
  • Div-based toggle switch styled like .form-switch
  • "Only $240!" add-on out of context
  • "Choose" and "Submit" button labels
  • transition: all .3s ease-in on cards
  • *:focus { outline: none; box-shadow: none !important }
  • No dark mode
  1. P0 Lens: clarify

    Real costs are hidden in the fine print

    $4.99/mo per extra bank connection, the trial turning read-only, refunds only within 30 days and cancelling via support all sit in a 10px #adb5bd paragraph below the fold. Priya finds out on her first invoice.

  2. P0 Lens: quieter

    Manipulative patterns

    A 24h countdown that resets on every visit, "No thanks, I like doing taxes by hand" as the decline link, and "Only $240!" with an Add to Cart button. Each one tells her the page is working against her.

  3. P1 Lens: distill

    Five plans for one kind of buyer

    Free and Enterprise don't fit a freelancer, all five are the same Bootstrap card with the same blue or gray button, and the feature lists use different wording per card, so Priya can't tell what Pro adds over Starter without the table.

  4. P1 Lens: harden

    The toggle and comparison are inaccessible

    The billing switch is a div styled like .form-switch with a click listener, so it has no role, state or keyboard access. The table marks features with red ✗ / green ✓ glyphs only, with no text alternative, and `*:focus { outline: none; box-shadow: none !important }` kills Bootstrap's focus ring.

  5. P2 Lens: clarify

    The add-on is priced out of context

    The CPA review sits alone under the plans as "Only $240!". She has to work out that it's $20/mo and add it to Pro herself.

The changes

Before, after, and why.

The report Pristine hands back after a run, with the real values from the two pages above.

LensBeforeAfterWhy
delightSticker prices only; "$4.99/connection" in 10px #adb5bd fine printSetup panel: accounts stepper (1–12, 44px buttons) + CPA checkbox; each card gets a receipt: "Starter plan $12 · 2 extra accounts × $4.99 $9.98 · Your total $21.98/mo · $263.76 a year at checkout"The price she sees is the price she'll pay, worked out for her setup.
clarifybg-warning "Most popular" badge on Pro, alwaysbestFit(accounts, period): cheapest plan with tax estimates. At 9 accounts annual Pro is $57.94 vs Business $56, so the "Best fit for you" badge and primary CTA move to Business, with the reason in a sentenceA recommendation that changes with her answers is one she can trust.
delightNo way to compare plans as usage growsSVG cost curve, 1–12 accounts: Starter dashed, Pro and Business solid, a marker at the crossover ("Business cheaper from 9 accounts") and dots that slide to her count over 260msShows the break-even point instead of making her do the arithmetic.
quieter.alert-bar (alert-warning) "Limited time: 20% off annual plans! Offer ends in 23:59:58"Removed. Annual billing is a plain 20% discount: "Plan price, billed yearly. Saves $84 a year."A fake deadline is a lie. The real saving is persuasive enough on its own.
harden<div class="switch" id="switch"></div> with a click listener<fieldset> with two radios as a segmented control; body:has(#bill-annual:checked) [data-period="monthly"] { display: none; } so prices, receipts and the chart switch with JS offKeyboard and screen-reader users can operate it, and it works without JS.
animatev1: price swap animation ran on first page loadOnly changed values animate, via el.animate() (220ms, translateY 3px → 0); CPA line opens with grid-template-rows 0fr → 1fr; reduced motion gets opacity onlyMotion confirms what changed, and nothing moves when the page loads.
distill5 plans: Free, Starter, Pro, Business, Enterprise "Custom"3 plans with "Everything in Starter, plus" lists; Starter says plainly "No quarterly tax estimates or invoice reminders"Fewer choices that differ in clear steps, with the gap named on the cheap plan.
clarify.fine { font-size: .65rem; color: #adb5bd; }"No surprises on your card": trial ("Start today and it runs until Nov 21"), one-click cancel, 30-day annual refundsThe facts that cause refunds and churn are read before signing up.
adaptRed ✗ / green ✓ glyphs with no text; .table-responsive scrolls six columns sideways at 390pxLabelled check/minus icons, <caption>, scope headers; under 640px each row becomes the feature name over three values labelled via td::before { content: attr(data-plan) }The comparison stays readable on a phone without sideways scrolling.
colorizeStock Bootstrap: #0d6efd on nearly every button, warning-yellow banner and badge; v1 accent #4b3bc4Shared Ledgerline tokens: --accent: #1d5a85 on #f8f7f3; dark --bg: #101417, --accent: #86bde3Gives Ledgerline its own colour, matches the landing page, and lets one action lead.