Repository navigation
fix(public): persistent labels on both appraisal intake fields and brand-consistent document titles on /pricing and /brief-requested #67
Changes from 9 commits
4555252
151cd77
376c9e1
a629d22
861c4c3
b207ccb
4e3dd6a
ca82a49
4305aa5
05b193d
e84317f
da55336
e833312
6c9b00e
aeb9046
e579060
d02d0e4
0a46aaa
38b00bc
ce8b2e6
b904de2
b0f7efe
beeac3c
3e44c6e
fc193df
06e7e10
0359f56
086da94
2271355
40691a7
53f8dcb
55efdd5
3e7d669
d28b460
7dcf48b
d5be818
2ed1508
c3942ea
b371b1b
a5601c3
9b09d8c
5c7b92b
389e347
4cc8a1a
6d128ca
e2710c5
3c13999
49e1393
eadbad1
741838c
c79cc4c
4c6d4fd
0e4a87a
bf80e42
599c124
71797e0
7592db0
b390d69
9ca4688
3f6698d
503c2a0
67ba587
ef2ee4b
6c5f0c3
28a3d92
a2695b4
8a9463f
7c534df
20439d0
e25378e
70176ec
cbf7f58
acb62b1
c4527e3
98b7cd1
5544b27
22f535e
f88b2af
ade833b
8890934
be782cd
8aa70e2
cc2f929
3afad78
a680be1
370fad5
fbf7373
08745f9
f2b3041
33d2a97
edb99ce
d55177d
318ffd7
73f4ec9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1495,6 +1495,63 @@ for (const [pageName, pageHtml, expected] of canonicalPages) { | |
| } | ||
| } | ||
|
|
||
| // ---- Document titles (brand consistency) ---------------------------------- | ||
| // Two served pages still branded themselves "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 title said | ||
| // "TinyStudio": /pricing served "Pricing & terms — The Tiny Studio" and | ||
| // /brief-requested served "Request received — The Tiny Studio", both | ||
| // byte-identical on origin/main. Title tags are a first-order SERP signal, so | ||
| // every one of the six served appraisal pages must now name the brand in its | ||
| // document title and must never return the spaced "The Tiny Studio" form. | ||
| // The retired /agent-desk surface is deliberately excluded: its title frames | ||
| // itself as retired and it is noindex. | ||
| const titlePages = [ | ||
| ["homepage", siteHome], | ||
| ["audit page", siteAudit], | ||
| ["desk page", read("public/agents.html")], | ||
| ["pricing page", read("public/pricing.html")], | ||
| ["specimen page", read("public/specimen.html")], | ||
| ["brief-requested page", read("public/brief-requested.html")] | ||
| ]; | ||
|
|
||
| for (const [pageName, pageHtml] of titlePages) { | ||
| const title = pageHtml.match(/<title>([^<]*)<\/title>/i)?.[1] ?? ""; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a page contains an earlier commented-out title such as Useful? React with 👍 / 👎. |
||
| if (!title) { | ||
| failures.push(`Document title must exist on ${pageName}.`); | ||
| continue; | ||
| } | ||
| if (!title.includes("TinyStudio")) { | ||
| failures.push(`Document title on ${pageName} must name TinyStudio (found ${JSON.stringify(title)}).`); | ||
| } | ||
| if (title.includes("The Tiny Studio")) { | ||
| failures.push(`Document title on ${pageName} must not use the spaced "The Tiny Studio" form (found ${JSON.stringify(title)}).`); | ||
| } | ||
| } | ||
|
|
||
| // ---- Intake field labels (activation) ------------------------------------- | ||
| // Both appraisal intake forms (homepage and /audit) labelled their fields | ||
| // only with placeholder text, which disappears the moment a buyer starts | ||
| // typing and is not a persistent programmatic label. Each intake input must | ||
| // carry a non-empty aria-label so the field keeps its name for assistive | ||
| // tech and for the browser's own validation announcements, no matter what | ||
| // the field contains. | ||
| const intakePages = [ | ||
| ["homepage", siteHome], | ||
| ["audit page", siteAudit] | ||
| ]; | ||
|
|
||
| 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; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If the email input is deleted or renamed, this Useful? React with 👍 / 👎. |
||
| const aria = tag.match(/\baria-label="([^"]*)"/)?.[1] ?? ""; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a developer replaces these attributes with associated visible Useful? React with 👍 / 👎. |
||
| if (!aria.trim()) { | ||
| failures.push(`Intake input on ${pageName} must carry a persistent programmatic aria-label (placeholder-only labels disappear as buyers type): ${tag}`); | ||
|
Comment on lines
+1848
to
+1854
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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 |
||
| } | ||
| } | ||
| } | ||
|
|
||
| for (const migration of ["migrations/0002_agent_runs.sql", "migrations/0003_agent_usage_limits.sql"]) { if (!existsSync(new URL(`../${migration}`, import.meta.url))) { | ||
| failures.push(`Missing migration: ${migration}`); | ||
| continue; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For speech-input users, the visible prompt is
yourwebsite.com, but the newaria-labeloverrides that text in the accessibility tree withYour website domain, which does not contain the visible wording; commands based on what the user sees may therefore fail to target the field. This mismatch is copied to both appraisal forms, so use a visible<label>or ensure the accessible name includes the placeholder text.Useful? React with 👍 / 👎.