📄

Exercise Buddy Finder: design critique

Private deliverable. Enter the hub password to continue.

That's not right. Try again.

← Back to the hub

Exercise Buddy Finder: design critique

Dual-agent review of exercisebuddyfinder.com. Design health 23/36, two P0 issues, six prioritized fixes.

Prepared 2026-08-06

Method: dual-agent (A: design review, isolated · B: detector + browser evidence, isolated)

Target: https://exercisebuddyfinder.com · Score 23/36 · 2 P0 · 2 P1 · 2026-08-06

Provenance notes: Assessment A could not capture raster screenshots (the browser pane would not composite frames), so it measured the rendered DOM directly at 1280x800 and 375x812 (computed styles, bounding rects, hit-testing, live contrast math) and read all of src/. Every geometric claim below is a measured number. Assessment B could not use the detector's own URL engine (Puppeteer is not installed), so it injected the same rule set into the live page instead and got full rendered-DOM coverage. The temporary local server it started is stopped and verified stopped; the repo is unmodified.

Design Health Score

# Heuristic Score Key Issue
1 Visibility of System Status 2 Real status messaging exists (role="status" on the count, per-buddy local time), but every unknown URL returns HTTP 200 with the homepage, and /buddies says "0 buddies" with no signal that the site is pre-launch rather than broken.
2 Match System / Real World 4 The site's strongest dimension. Zero jargon, human category names, timezone computed for the reader.
3 User Control and Freedom 2 Good escapes ("Use a different email", "Show everyone instead"), but the funnel's terminal state has no forward exit, there is no resend-code, and the suggestion dialog has no Escape handler.
4 Consistency and Standards 2 Three contradictory prices in one funnel, and "Apply to join" opens a member login.
5 Error Prevention 2 Good input constraints and availability auto-off, but nothing stops a prospective buddy walking into the member funnel.
6 Recognition Rather Than Recall 3 All nav is labeled text, no icon-only anything. Deducted because the buddy card has no face, so choosing between people is pure text recall.
7 Flexibility and Efficiency n/a Persuade surface with one select and one toggle; no repeat-use or expert path exists to accelerate.
8 Aesthetic and Minimalist Design 3 Genuinely restrained and well set. Deducted for being minimalist to the point of empty.
9 Error Recovery 2 Error copy is excellent; error mechanics are not. No resend, no retry control, and raw API error strings reach the reader.
10 Help and Documentation 3 A real /how-it-works page and explicit rules on /for-buddies, but none of it is contextual, and "is this safe" lives behind a 15.2px footer link.
Total 23/36 Acceptable (64%)

Heuristic 7 scored n/a under the Persuade mode-applicability rule, so the maximum is 36, not 40.

Design Specificity Verdict

The words are authored for this product. The design is not. Delete the copy and there is no product left in the composition.

LLM assessment. The voice is unmistakable and cannot be transplanted: "The hardest part is starting alone." "A friendly face who shows up at seven in the morning so that you do too." "It is 6:42 where they are." "Exercise buddy, not a certified trainer." The API internally says providers and the interface says buddies everywhere, which is a real act of care.

The composition is category-interchangeable in every respect. The hero is a left-aligned serif headline over a cream band with 508px of dead space to its right at 1280px, containing nothing. "How it works" is three white rounded rectangles with a 1px border, numbered 1/2/3, which is the single most-used marketing section on the web. The closing deep-teal band is universal. And the buddy card, the product's actual atom, the object the entire purchase decision rests on, is a bordered rectangle with a name, pill tags, a truncated bio, languages, a rate, and a button, with no face. It would serve a directory of plumbers or freelance copywriters unchanged.

There are zero images sitewide: no <img>, no <svg>, no CSS background images across all ten pages, on a product whose pitch is literally a friendly face. Three of the six declared brand colors (--sage, --rose, --gold) are referenced zero times anywhere in src/. Fonts are system stacks only, so the intended editorial serif renders as Georgia for most of a US/UK/CA Windows audience.

Two components are genuinely product-native and are the best design ideas in the codebase: the live green dot (a human is available this exact minute) and the certified-versus-buddy tag. They encode the only two questions that matter when choosing a buddy. Neither has ever been seen by a visitor, because the directory is empty.

Deterministic scan. The bundled detector found zero findings on the built markup (verified genuine, not a coverage miss: a synthetic control file correctly returned 3 findings). Injected into the live rendered DOM, it reported 11 anti-pattern groups at 375px and 4 at 1280px, across /, /buddies, /join and /how-it-works.

Of those, three are false positives against this project:

  • overused-font (roboto, 72% of text) is the standard system-UI stack resolving to its fourth fallback in Chromium, not a brand choice.
  • cream-palette (rgb 251,248,243) is a sanctioned page base in your visual taste profile, not a slop tell.
  • gpt-thin-border-wide-shadow fires only on the beta suggestion panel, the one element class you have exempted.

The nine body-text-viewport-edge hits at 375px are real but are one decision, not nine problems: the mobile gutter is 15px, so every paragraph reports it. They vanish above 768px.

Genuine detector findings the design review did not catch: a duplicate h1 in the served HTML of /join (a hidden signed-in-state heading that is invisible today but real to crawlers and to the accessibility tree the moment that state unhides), skipped heading levels on /join, and an unlabeled textarea in the suggestion widget (no name, no label, no aria-label).

Your hard rules: all clean. Zero em dashes anywhere in dist/ or src/. Zero horizontal overflow at 320, 390, 768, 1280, 1920 and 2560, with the container correctly capping at 1680px. The only fixed-position elements are the beta suggestion launcher and its panel, which is exactly the approved exemption. Contrast passes on all 10 distinct text pairs, worst case 7.20:1 against a 4.5:1 floor.

Visual overlays. No user-visible overlay is live. Injection succeeded and overlays did render during the run, but the temporary server has since been stopped, so there is nothing to look at in a browser now.

Overall Impression

This site's writing is better than 95% of what ships, and its design is doing none of the work. The gap between the two is the whole story.

But neither is the real problem. The real problem is that the homepage promises a roster and the button under it delivers an empty room, and the one page built to recruit the people who would fill that room sends them to a customer login instead. The site is currently a beautifully written door to nothing, with the doorbell wired to the wrong house.

Biggest single opportunity: put human faces on this site. It is a marketplace of people with zero photographs of people.

What's Working

  1. The voice is carrying the entire product. Concrete, unornamented, no wellness vocabulary, no "journey" or "unlock", no early CTA. The weight-loss medication section works because it discloses rather than sells, and "we are the introduction, not the middleman" explains a business model in seven words. That is also the diagnosis: it is the only thing making the site distinctive.

  2. Reading typography genuinely engineered for a 55+ audience. 20px base declared in rem so the reader's own browser setting still wins, 1.65 line-height, and a 41rem measure giving about 65 characters. Worst contrast on the page is 7.20:1 where the standard is 4.5:1. The rem decision in particular is the thing most sites get wrong for exactly this audience, and you got it right.

  3. Somebody thought hard about the empty case. Availability defaults OFF so the first screen is never empty, there is a "Show everyone instead" escape from a zero-result filter, and /buddy with a bad slug produces a clean "We could not find that buddy." The irony is that the global empty case, the one that matters, is the one left unhandled.

Priority Issues

[P0] The primary CTA leads to an empty marketplace, and nothing prepares the visitor for it.

  • What: "See who is available" goes to /buddies, which renders "0 buddies" and "No buddies in that category yet." All nine categories return zero. Two paragraphs earlier the homepage promises "Watch their videos, read what they do, see who is free right now."
  • Why it matters: the homepage's entire persuasive load is spent in one click, at the moment the visitor is most willing. Worse, the empty message says "that category" while the select reads "Everything", so it reads as a mistake the visitor made. They will try two or three of the nine options, get zero every time, and conclude the site is broken or abandoned.
  • Fix: until real profiles exist, replace the directory with an honest waiting surface ("We open in [month]. Here are the first four buddies joining") with real faces, real intro videos, and one email capture. Separately, fix the empty-state branch so it distinguishes "nobody in this category" from "nobody on the site yet", and never says "that category" when Everything is selected.
  • Suggested command: /impeccable onboard

[P0] "Apply to join" sends prospective buddies to the member signup, and no buddy application exists anywhere in the product.

  • What: the "Apply to join" button on /for-buddies links to /join, which is headed "Come in and have a look" and sells "The first members get six months free." There is no application form in src/ and no application route in the worker.
  • Why it matters: with zero buddies live, supply acquisition is the only blocking problem this business has, and the single page built to solve it terminates in the wrong form. A trainer in Manila reads a page telling them an intro video is required and their NASM certification will be verified with the certifying body, clicks the one button on the page, and is asked for an email so they can get a free membership. They close the tab.
  • Fix: build a real application collecting exactly what the page already promises (name, country, timezone, categories, languages, rate, certifying body and credential number, intro video URL) posting to a new applications endpoint. Relabel /join to "Sign in" everywhere so the two funnels can never collide again.
  • Suggested command: /impeccable shape

[P1] On a phone, the floating suggestion widget covers 115px of the 234px-wide hero CTA at first paint.

  • What: measured at 375x812, scroll position zero. The CTA occupies x 15 to 249; the launcher occupies x 134 to 359, overlapping 115px horizontally and 53px vertically. Hit-testing at the CTA's right side returns the launcher button, not the CTA. Nearly half the primary conversion button is not tappable. Separately the CTA's bottom edge sits at 805px of an 812px viewport, so on an iPhone SE or 8 class device it is entirely below the fold, behind a 161px header whose nav wraps to two rows.
  • Why it matters: the widget is your one approved fixed element and it stays, but the exemption covers a feedback launcher, not a feedback launcher that eats the primary CTA. A right-handed thumb lands on the right half of a button by default, so the natural tap opens a text box instead of converting. Above the fold the page currently shows a headline plus three paragraphs before the button, against your house rule of one headline and one CTA.
  • Fix: cut the hero to headline plus one sentence plus CTA so the button lands around y 450 on a phone (the second paragraph duplicates the How It Works section and belongs there). Independently, shrink the launcher to an icon plus short label below 520px and reserve a bottom safe zone so no large button can render inside the launcher's rect.
  • Suggested command: /impeccable adapt

[P1] The product asks strangers to meet strangers alone on video, and there is no trust or safety design in the interface.

  • What: the words "report", "block", "review" and "rating" appear nowhere in src/. A profile shows name, city, live dot, certification tag, video, bio, languages, rate. After payment the member receives a personal email address and phone number, followed by a card saying the platform is not involved and takes no cut. The strongest safety sentence on the site ("We suspend first and ask questions afterwards on anything involving your safety") is in /terms, behind a 15.2px footer link, on a page that opens by admitting no lawyer has reviewed it.
  • Why it matters: this is the highest-stakes moment in the product and the interface answers it with a disclaimer. A disclaimer stands where reassurance belongs. The exposure is also one-directional: a buddy's personal phone number goes to any member, with no report path for either party. This is the difference between a marketplace and a list.
  • Fix: put trust on the profile, not in the terms. State what was actually checked ("Identity verified · Certification confirmed with NASM on 12 March · 40 sessions completed"). Add a visible "Report a problem" control on every profile and inside the contact-reveal card. Replace the "we are not in the middle" card with what the platform will do, using the sentence already sitting in /terms.
  • Suggested command: /impeccable harden

[P2] Half the palette is dead, there are no images, and the composition does no work.

  • What: --sage, --rose and --gold are declared and referenced zero times. Zero images sitewide. System font stacks only, so the intended serif renders as Georgia for most of the audience. The hero leaves 508px of empty space to the right of the prose column at 1280px.
  • Why it matters: for a marketplace of human beings, shipping zero human faces is not minimalism, it is absence. The buddy card, where the purchase decision happens, has no photograph, which is the one thing people actually decide on. Meanwhile the palette claims a warmth the rendered page never delivers.
  • Fix: add a photograph to the buddy card and a headshot to the profile (applicants already supply an intro video, so the poster frame is free). Fill the hero's empty 508px with one aspirational-realism photograph. Spend sage on the non-certified tag and gold or rose as the live-dot accent, or delete the tokens. Self-host one real variable serif so the brand looks the same on Windows as on a Mac.
  • Suggested command: /impeccable colorize

[P2] A cluster of accessibility defects that a 55+ audience will feel.

  • What: zero :focus or :focus-visible rules in the entire stylesheet, so keyboard users get only the browser default ring, which against a dark teal button with a matching teal border is close to invisible. Five tap targets fall under 44x44 at 390px (the brand link at 32px tall, both nav links at 25px, and the Privacy and Terms footer links at 20px tall and under 47px wide, failing on both axes). A duplicate h1 and two skipped heading levels in the served HTML of /join, one skipped level on /buddies. An unlabeled textarea in the suggestion widget. No skip link past the 161px header. Every buddy card carries two links to the same place, doubling tab stops.
  • Why it matters: your stated audience is women over fifty, a group with meaningfully higher keyboard use, browser zoom, and touch imprecision. You did the hard accessibility work already (the rem sizing, the contrast) and then left the cheap parts undone.
  • Fix: add a real focus-visible style, raise nav and footer link hit areas to 44px minimum with padding, give the textarea a label, and fix the heading order.
  • Suggested command: /impeccable audit

Persona Red Flags

Jordan (Confused First-Timer) is the primary persona for this surface, and the one it fails hardest.

  • Clicks "See who is available", the single thing the page instructed, and gets "0 buddies. No buddies in that category yet." Jordan takes labels literally, so they will believe they chose wrong, open the nine-option Show select, try two or three, get zero each time, and leave convinced they broke it. The select says "Everything" while the message says "that category", a direct contradiction Jordan cannot resolve.
  • Is quoted three different prices in one funnel: "$4.99 a month" on the homepage, "$4.99 a month, or $49.99 for the year" on a buddy profile, and "it is free right now, no card" on /join. Jordan will not know what they are agreeing to.
  • Completes the entire signup, enters email, waits for the code, types six digits, and the reward is "You do not have access yet", with instructions to click a corner button and ask someone named Annette for an invitation. Annette is named exactly once, mid-homepage, with no photo and no byline. Jordan does not know who that is. This is where Jordan leaves permanently.
  • The question Jordan actually has ("who is this person, and what happens if they're awful?") is answered nowhere in the flow.

Casey (Distracted Mobile User)

  • The hero CTA's bottom edge is at 805px of an 812px viewport. On an iPhone SE or 8 it is entirely below the fold, behind a header taking 20% of the screen whose three nav links wrap onto two rows.
  • The floating widget covers the right 115px of the 234px CTA. Casey thumbs where a right-handed thumb naturally lands and opens a text dialog instead of converting. A mis-tap into text entry is the worst possible outcome for a one-handed, interrupted user.
  • On /buddies, every touch target is under the 44x44 minimum: the "Only people free right now" label is 33px tall, its checkbox 19x19, the category select 42px.
  • The one-time-code field is genuinely right for Casey. But there is no resend, so if Casey is interrupted and the ten minutes lapse, the only control offered is "Use a different email", which is neither what happened nor what they need.

Riley (Deliberate Stress Tester)

  • /definitely-not-a-real-page-xyz, /signup, /login, /pricing and /buddies/someone all return HTTP 200 with the homepage, byte-identical. A soft 404 on every path, found in the first minute.
  • "Apply to join" promises an application and delivers a member login. A control that appears to work and silently does something else is Riley's signature find.
  • The suggestion dialog has a dialog role but no modal attribute, no focus trap, no Escape handler, and no focus return on close. Opening it moves focus into the textarea with no keyboard route back out.
  • Refreshing mid-auth destroys the flow: the code step is not persisted, so a refresh after the email arrives drops Riley back to the email form while a still-valid code sits in their inbox with no field to type it into.
  • Credit where due: /buddy with no slug and with a nonsense slug both produce a clean "We could not find that buddy. Back to the list."

Minor Observations

  • The contact phone renders as plain text, not a tappable link, so mobile members must transcribe it by hand at the exact moment they are trying to reach out.
  • /terms opens by stating a lawyer has not reviewed it. Admirably honest, and it should not be publicly visible on a site about to take money.
  • "You agree a time and a price" reads British. The American construction is "you agree on a time." Audience is US-first.
  • /buddy?slug= is a query-string route. Fine while noindexed, but every future indexable profile depends on it, and changing it later means a redirect map.
  • The site is correctly noindex/nofollow pre-launch, with the reasoning left in the source.
  • The homepage is exceptionally light: three network requests, 4.8KB transferred, 90 DOM nodes, interactive in 96ms. That is a real asset, and adding photographs will cost some of it. Spend it deliberately.

Questions to Consider

  • What if the homepage led with four real faces instead of four paragraphs? The product is "a friendly face who shows up", and the page contains no faces at all.
  • Your own /for-buddies page calls the introduction video "the single biggest reason someone chooses one buddy over another." If that is true, why is it absent from the card and buried below the fold on the profile? What would this site look like if the video were the card?
  • Who vouches for these people? The interface's current answer is "nobody, and we take no cut." What is the smallest true claim you could put on a profile that would change a hesitant woman's mind, and what would you have to actually do to earn the right to make it?
  • The empty directory is the truth. What if the homepage said so? "We open in September with 30 buddies. Here are the first four." Would that convert better than promising a roster and delivering zero?
  • Three of your six brand colors have never touched a pixel. Is the palette aspirational, or is the page under-designed? Those need different fixes.
  • What would a confident version of the $4.99 ask look like if it appeared once, in one place, with one number, instead of three times with three different answers, none of which can currently be paid?

Published to Annette's hub. Rebuilt from the source markdown, so edit the source and rerun rather than editing this page.