Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b34e395
fix(public): put a real Request-the-appraisal signup form in the /pri…
nish3451 Aug 11, 2026
c13aadb
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
db9f2d5
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
e5d81f7
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
5fc5325
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
28c0263
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
56b5419
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
7114fd7
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
2883793
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
4fab41d
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
abd7110
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
213c730
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
470dde5
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
4ee6a10
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
387ea89
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
6a7992d
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 12, 2026
d5644dd
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
fe21193
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
43dc65a
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
8bde0ce
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
48e7679
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
efaf76f
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
cc725e1
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
c665939
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
22d3b93
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
a6b4bae
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
5b1cdb5
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
5355ad8
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
f88197c
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
0cc90ab
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
1dec4ce
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
e3e4d6b
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
29d695e
Merge branch 'main' into fix/pricing-closing-callout-appraisal-action…
nish3451 Aug 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions public/pricing.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ <h2>Before you ask</h2>
<div class="band">
<h2>The appraisal costs you an email. The rest is a decision you can make later.</h2>
<p>Six a month, done by hand. When this month's sixth is taken the intake closes until the next one opens.</p>
<form class="lead two" action="/api/signups" method="post">
<input type="text" name="website" required inputmode="url" autocomplete="url" placeholder="yourwebsite.com" aria-label="Your website domain" pattern="(https?://)?([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}(:[0-9]+)?(/[^\s]*)?" title="Enter your domain, like example.com">
Comment on lines +132 to +133

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stack the pricing form at tablet widths

On /pricing at widths just above 760px, the shared .two form remains a single row even though the band's 62px side padding leaves only 524px at a 768px viewport. The nowrap submit button then leaves each input about 160px wide including 42px of input padding, clipping the yourwebsite.com placeholder and leaving sighted users without a readable field prompt. Add a pricing-specific earlier stacking breakpoint (similar to the homepage's 900px treatment) or otherwise preserve enough input width.

Useful? React with 👍 / 👎.

<input type="email" name="email" required placeholder="Your work email" aria-label="Your work email">
Comment on lines +133 to +134

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Increase placeholder contrast in the dark-band form

In the new pricing-band form, the placeholders are the only visible field labels, but the shared #AC9E8B placeholder color is rendered against a 74%-opaque light form background composited over the band’s #1C1712#100C09 gradient, producing only about 1.4–1.5:1 contrast. This makes both blank controls difficult for low-vision users to identify; add persistent visible labels or use a placeholder color/background combination that meets normal-text contrast requirements.

Useful? React with 👍 / 👎.

Comment on lines +133 to +134

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore distinct keyboard focus on pricing inputs

When a keyboard user tabs through this new form, both inputs inherit form.lead input { outline:none } from public/shared.css:61, while only form:focus-within changes the outer form border. That border remains identical when focus moves from website to email, so sighted keyboard users cannot tell which control will receive typing; preserve the browser outline or add a per-input :focus-visible indicator.

Useful? React with 👍 / 👎.

<button>Request the appraisal</button>
</form>
<div class="note">No revenue, ranking, ROAS, conversion, booked-call or sales-volume guarantees. The delivery guarantee above is the only promise we make about outcomes, and it is a promise about our work, not your market.</div>
</div>

Expand Down
27 changes: 27 additions & 0 deletions scripts/check-site.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,33 @@ if (!retiredDesk.includes("role=\"tabpanel\"") || !retiredDesk.includes("aria-la
failures.push("Agent output must expose a proper tabpanel relationship.");
}

// Pricing closing-callout regression (Grok finding: the /pricing closing band
// ended in a dead end — "The appraisal costs you an email" with no way to send
// one — while every other served conversion surface carried a real intake
// form). The band must keep the actual signup form: a form.lead inside the
// .band posting website + email to /api/signups, both fields with a
// persistent programmatic aria-label, and a submit button reading "Request
// the appraisal". STATIC SOURCE GUARD (regex over pricing.html), matching the
// repo's other source-string guards.
const sitePricing = read("public/pricing.html");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply the website-field guard to pricing

The new pricing form is not added to the website validation loop above, which still checks only siteHome and siteAudit. If this copied input later regresses to type="url", loses its domain pattern, or accepts malformed values, npm run check will remain green even though pricing users can no longer submit the same bare domains as on the other intake surfaces; include sitePricing in that shared validation.

Useful? React with 👍 / 👎.

const pricingBand = sitePricing.match(/<div class="band">([\s\S]*?)<\/div>\s*<section id="confidential">/)?.[1] ?? "";
const pricingForm = pricingBand.match(/<form\b[^>]*class="lead[^>]*"[^>]*>[\s\S]*?<\/form>/i)?.[0] ?? "";

if (!pricingForm || !pricingForm.includes('action="/api/signups"') || !pricingForm.includes('method="post"')) {
failures.push("Pricing closing callout must carry the real signup form (form.lead posting website + email to /api/signups) so the appraisal ask is actionable in place.");
}
for (const input of pricingForm.matchAll(/<input\b[^>]*>/gi)) {
const tag = input[0];
if (!/\bname="(?:website|email)"/.test(tag)) continue;
Comment on lines +315 to +317

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require both signup fields in the pricing guard

If either website or email is deleted or renamed while the form and button remain, this loop simply skips the missing field and npm run check still passes. In particular, losing website would allow the form to save a signup with no site to appraise because the worker accepts a null normalized website. Explicitly assert that both named, required inputs exist before validating their labels.

Useful? React with 👍 / 👎.

const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? "";
if (!aria.trim()) {
failures.push(`Pricing intake input must carry a persistent programmatic aria-label (placeholder-only labels disappear as buyers type): ${tag}`);
}
}
if (!/Request the appraisal/i.test(pricingForm)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require an actual submit button in the guard

If the button is removed or changed to a non-submitting element while the phrase “Request the appraisal” remains anywhere in the form, this regex still passes, even though users no longer have a clickable way to submit the two-field form. Match the text specifically inside a <button> or submit input so the dead-end regression this guard is intended to prevent cannot return unnoticed.

Useful? React with 👍 / 👎.

failures.push('Pricing closing callout submit button must read "Request the appraisal".');
}

// Mobile layout regression: at 390x844 the /audit page previously overflowed
// horizontally (navlinks measured to x=569, the 53-of-89 stat to x=451).
// The mobile treatment must live in audit.css behind the shared 760px
Expand Down
Loading