Skip to content

fix(public): persistent labels on both appraisal intake fields and brand-consistent document titles on /pricing and /brief-requested - #67

Merged
nish3451 merged 94 commits into
mainfrom
fix/intake-labels-and-stale-titles
Aug 15, 2026
Merged

fix(public): persistent labels on both appraisal intake fields and brand-consistent document titles on /pricing and /brief-requested#67
nish3451 merged 94 commits into
mainfrom
fix/intake-labels-and-stale-titles

Conversation

@nish3451

@nish3451 nish3451 commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

What

Self-directed live walk (tier 1–2: public-promise gaps and UX breakage) found two fresh, uncovered defects on the served product — both confirmed live at 390×844 and 1280px on 2026-08-10, both byte-identical on origin/main, both absent from every open PR's diff.

1. Intake fields had no persistent programmatic labels (homepage + /audit).
Both form.lead intakes labelled their website and email inputs only with
placeholder text, which disappears the moment a buyer starts typing and is
not a programmatic label. Live DOM: aria=null, hasLabel=false on all four
inputs. Both pages now ship a stable aria-label on each input (placeholders
stay as visual hints).

2. Two document titles still branded the site "The Tiny Studio".
/pricing served Pricing & terms — The Tiny Studio and /brief-requested
served Request received — The Tiny Studio — the spaced name the site's own
identity copy disavows (it collides with "The Tiny Studio LA" and other
unrelated businesses), while every other page said TinyStudio. The pricing
<title> also contradicted its own og:title (TinyStudio — Pricing & terms).
Both titles now name the brand; pricing's title matches its og:title exactly.

Deterministic guards (fail on origin/main, pass here):

  • scripts/check-site.mjs now asserts all six served appraisal pages'
    document titles name TinyStudio and never contain The Tiny Studio
    (the retired /agent-desk page is deliberately excluded: its title frames
    itself as retired and it is noindex).
  • scripts/check-site.mjs now rejects any website/email intake input on
    the homepage or /audit that lacks a non-empty aria-label.

Files

  • public/index.html — aria-label on website + email inputs
  • public/audit.html — aria-label on website + email inputs
  • public/pricing.html — title → TinyStudio — Pricing &amp; terms
  • public/brief-requested.html — title → Request received — TinyStudio
  • scripts/check-site.mjs — the two regression guards above

Verification

  • npm test green: check + headings 6/6 + sitemap 7/7 + worker 53/53 + ui 16/16
  • npm run check:render-blocking — all six pages PASS under production CSP
  • npx wrangler deploy --dry-run — passes (after removing a 0-byte
    /home/nish/package.json environment artifact that broke esbuild's upward
    package.json lookup on this box; traced to backlog-console/actions.log)
  • Live walk 390×844 + 1280px on all six pages: zero overflow, zero console
    errors (only the known /brief-requested placeholder gtag CSP error,
    already owned by PR fix(worker): make the Google Ads conversion tag env-driven instead of a dead placeholder #52)

intended-outcome: no served appraisal page can brand itself "The Tiny Studio" in its document title again, and no appraisal intake field can lose its programmatic label when placeholder text disappears.

verify: npm run check

Summary by CodeRabbit

  • Accessibility

    • Added clear, accessible labels to website and work-email fields in signup and appraisal request forms.
  • Updates

    • Standardized page titles to use “TinyStudio” branding across pricing and request-confirmation pages.
  • Quality Improvements

    • Added automated checks to help ensure consistent page titles and accessible form labels across supported pages.

…kill the two "The Tiny Studio" document titles

The homepage and /audit intake forms labelled their fields only with
placeholder text, which disappears the moment a buyer starts typing and is
not a persistent programmatic label; both served pages now carry a stable
aria-label on the website and email inputs. /pricing and /brief-requested
still branded their document titles "The Tiny Studio" — the spaced name the
site's own identity copy disavows — while every other page said TinyStudio;
both titles now match the brand (and the pricing title matches its own
og:title). Two deterministic guards in check-site.mjs make both regressions
impossible: every one of the six served appraisal titles must name TinyStudio
and never "The Tiny Studio", and every intake website/email input must carry a
non-empty aria-label. The retired /agent-desk page is excluded deliberately:
its title frames itself as retired and it is noindex.

verify: npm run check

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@nish3451, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 58 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 89855e13-ffc8-4f94-830b-a3a53b3d7edb

📥 Commits

Reviewing files that changed from the base of the PR and between 376c9e1 and e833312.

📒 Files selected for processing (1)
  • scripts/check-site.mjs
📝 Walkthrough

Walkthrough

The pull request standardizes TinyStudio page titles, adds accessible labels to homepage and audit intake inputs, and extends scripts/check-site.mjs with title and accessibility validation.

Changes

Branding and accessibility validation

Layer / File(s) Summary
TinyStudio title consistency
public/brief-requested.html, public/pricing.html, scripts/check-site.mjs
Two page titles now use TinyStudio. Site checks validate titles across six appraisal pages and reject the spaced The Tiny Studio branding.
Intake input accessibility
public/audit.html, public/index.html, scripts/check-site.mjs
Homepage and audit website and email inputs now have non-empty aria-label attributes. Site checks validate these labels.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes both main changes: persistent intake-field labels and brand-consistent document titles on the specified pages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/intake-labels-and-stale-titles

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45552528f8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/check-site.mjs
];

for (const [pageName, pageHtml] of titlePages) {
const title = pageHtml.match(/<title>([^<]*)<\/title>/i)?.[1] ?? "";

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 Ignore inert titles before validating the document title

When a page contains an earlier commented-out title such as <!-- <title>TinyStudio — old</title> -->, this raw-source regex selects that match and can let a missing or misbranded live title pass the check. Strip HTML comments and inspect the <head>—as the canonical check immediately above already does—before asserting the title, ideally also verifying that exactly one live title exists.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/check-site.mjs`:
- Around line 1541-1547: Update the intake input validation loop in the
site-check logic to parse HTML attributes with flexible whitespace and either
single or double quotes, so both name and aria-label values are recognized.
Track matching fields per page and add failures when the expected website and
email inputs are absent, while preserving the existing requirement for non-empty
programmatic aria-labels.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bacbbf26-7293-4d58-bc95-a3e849acb60d

📥 Commits

Reviewing files that changed from the base of the PR and between 1295f9c and 4555252.

📒 Files selected for processing (5)
  • public/audit.html
  • public/brief-requested.html
  • public/index.html
  • public/pricing.html
  • scripts/check-site.mjs

Comment thread scripts/check-site.mjs
Comment on lines +1541 to +1547
for (const [pageName, pageHtml] of intakePages) {
for (const input of pageHtml.matchAll(/<input\b[^>]*>/gi)) {
const tag = input[0];
if (!/\bname="(?:website|email)"/.test(tag)) continue;
const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? "";
if (!aria.trim()) {
failures.push(`Intake input on ${pageName} must carry a persistent programmatic aria-label (placeholder-only labels disappear as buyers type): ${tag}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the intake-field check robust to valid HTML syntax.

Lines 1542-1547 only recognize exact double-quoted name and aria-label attributes. A valid name='website' input is skipped, and a valid aria-label='...' value is reported as missing. The loop also passes when a page has no matching inputs. Use a quote- and whitespace-tolerant matcher or parser, and assert that each page contains the expected website and email fields.

Proposed matcher fix
-    if (!/\bname="(?:website|email)"/.test(tag)) continue;
-    const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? "";
+    const nameMatch = tag.match(/\bname\s*=\s*(['"])(website|email)\1/i);
+    if (!nameMatch) continue;
+    const aria = tag.match(/\baria-label\s*=\s*(['"])(.*?)\1/i)?.[2] ?? "";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check-site.mjs` around lines 1541 - 1547, Update the intake input
validation loop in the site-check logic to parse HTML attributes with flexible
whitespace and either single or double quotes, so both name and aria-label
values are recognized. Track matching fields per page and add failures when the
expected website and email inputs are absent, while preserving the existing
requirement for non-empty programmatic aria-labels.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 151cd77949

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/check-site.mjs
for (const [pageName, pageHtml] of intakePages) {
for (const input of pageHtml.matchAll(/<input\b[^>]*>/gi)) {
const tag = input[0];
if (!/\bname="(?:website|email)"/.test(tag)) continue;

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 each intake field before checking its label

If the email input is deleted or renamed, this continue leaves the page with zero matching email fields and records no failure, even though signupResponse rejects submissions without body.email (src/worker.js:352-359). I verified that deleting both email inputs still lets node scripts/check-site.mjs pass, so the new guard cannot prevent a regression that breaks the appraisal intake; assert that each page contains exactly one website and one email field before validating their labels.

Useful? React with 👍 / 👎.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@nish3451
nish3451 merged commit e72e59b into main Aug 15, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant