Skip to content
This repository was archived by the owner on Oct 12, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@
"product:truth": "node scripts/check-product-truth.mjs",
"mobbin:run": "node scripts/run-design-system-proving-lab.mjs",
"mobbin:check": "node scripts/run-design-system-proving-lab.mjs --dry-run",
"ci": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-direction-proof-gate.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/test-operator-check-strictness.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && node scripts/test-public-conversion-signal.mjs && node scripts/test-public-structured-data.mjs && node scripts/test-public-brand-disambiguation.mjs && node scripts/test-public-heading-hierarchy.mjs && node scripts/test-public-link-targets.mjs && node scripts/test-public-social-preview.mjs && node scripts/test-public-theme-color.mjs && node scripts/test-public-soft-404.mjs && node scripts/test-public-deploy-bundle.mjs && node scripts/test-deploy-public-site-workflow.mjs && node scripts/test-pages-release.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check",
"ci": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-direction-proof-gate.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/test-operator-check-strictness.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && node scripts/test-public-conversion-signal.mjs && node scripts/test-public-structured-data.mjs && node scripts/test-public-brand-disambiguation.mjs && node scripts/test-public-heading-hierarchy.mjs && node scripts/test-public-link-targets.mjs && node scripts/test-public-social-preview.mjs && node scripts/test-public-theme-color.mjs && node scripts/test-public-soft-404.mjs && node scripts/test-public-deploy-bundle.mjs && node scripts/test-deploy-public-site-workflow.mjs && node scripts/test-pages-release.mjs && node scripts/test-public-brand-tagline.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check",
"check": "npm test",
"test": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-direction-proof-gate.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/test-operator-check-strictness.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && node scripts/test-public-conversion-signal.mjs && node scripts/test-public-structured-data.mjs && node scripts/test-public-brand-disambiguation.mjs && node scripts/test-public-heading-hierarchy.mjs && node scripts/test-public-link-targets.mjs && node scripts/test-public-social-preview.mjs && node scripts/test-public-theme-color.mjs && node scripts/test-public-soft-404.mjs && node scripts/test-public-deploy-bundle.mjs && node scripts/test-deploy-public-site-workflow.mjs && node scripts/test-pages-release.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check",
"test": "node scripts/test-service-engine.mjs && node scripts/test-sales-intake-contract.mjs && node scripts/test-active-offer-projection.mjs && node scripts/test-active-operator-surfaces.mjs && node scripts/test-direction-proof-gate.mjs && node scripts/test-client-readiness-contract.mjs && node scripts/test-validated-service-client.mjs && node scripts/test-client-acceptance-gates.mjs && node scripts/test-operator-check-strictness.mjs && node scripts/check-product-truth.mjs && node scripts/check-human-service-kit.mjs && node scripts/test-design-system-proving-lab.mjs && node scripts/check-retention-automation.mjs && node scripts/test-retention-automation.mjs && node scripts/check-agency-defaults.mjs && node scripts/check-outbound-claim-safety.mjs && node scripts/check-outbound-send-readiness.mjs && node scripts/test-outbound-send-readiness.mjs && node scripts/test-public-conversion-signal.mjs && node scripts/test-public-structured-data.mjs && node scripts/test-public-brand-disambiguation.mjs && node scripts/test-public-heading-hierarchy.mjs && node scripts/test-public-link-targets.mjs && node scripts/test-public-social-preview.mjs && node scripts/test-public-theme-color.mjs && node scripts/test-public-soft-404.mjs && node scripts/test-public-deploy-bundle.mjs && node scripts/test-deploy-public-site-workflow.mjs && node scripts/test-pages-release.mjs && node scripts/test-public-brand-tagline.mjs && find scripts -name '*.mjs' -print0 | xargs -0 -n1 node --check",
"site:publish": "node scripts/publish-public-site.mjs",
"site:publish:check": "node scripts/publish-public-site.mjs --prepare-only"
},
Expand Down
2 changes: 1 addition & 1 deletion public/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<span class="brand-mark" aria-hidden="true">TS</span>
<span class="brand-copy">
<strong>Tiny Studio</strong>
<span>Independent iPhone apps</span>
<span>Products for people and teams</span>
</span>
</a>
<nav class="top-nav" aria-label="Primary">
Expand Down
2 changes: 1 addition & 1 deletion public/contact/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<span class="brand-mark" aria-hidden="true">TS</span>
<span class="brand-copy">
<strong>Tiny Studio</strong>
<span>Independent iPhone apps</span>
<span>Products for people and teams</span>
</span>
</a>
<nav class="top-nav" aria-label="Primary">
Expand Down
2 changes: 1 addition & 1 deletion public/privacy-choices/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<span class="brand-mark" aria-hidden="true">TS</span>
<span class="brand-copy">
<strong>Tiny Studio</strong>
<span>Independent iPhone apps</span>
<span>Products for people and teams</span>
</span>
</a>
<nav class="top-nav" aria-label="Primary">
Expand Down
2 changes: 1 addition & 1 deletion public/privacy/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<span class="brand-mark" aria-hidden="true">TS</span>
<span class="brand-copy">
<strong>Tiny Studio</strong>
<span>Independent iPhone apps</span>
<span>Products for people and teams</span>
</span>
</a>
<nav class="top-nav" aria-label="Primary">
Expand Down
2 changes: 1 addition & 1 deletion public/support/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
<span class="brand-mark" aria-hidden="true">TS</span>
<span class="brand-copy">
<strong>Tiny Studio</strong>
<span>Independent iPhone apps</span>
<span>Products for people and teams</span>
</span>
</a>
<nav class="top-nav" aria-label="Primary">
Expand Down
2 changes: 1 addition & 1 deletion public/terms/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<span class="brand-mark" aria-hidden="true">TS</span>
<span class="brand-copy">
<strong>Tiny Studio</strong>
<span>Independent iPhone apps</span>
<span>Products for people and teams</span>
</span>
</a>
<nav class="top-nav" aria-label="Primary">
Expand Down
86 changes: 86 additions & 0 deletions scripts/test-public-brand-tagline.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { readFileSync } from "node:fs"
import { fileURLToPath } from "node:url"
import { dirname, join } from "node:path"

const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..")
const read = (p) => readFileSync(join(ROOT, p), "utf8")

let failures = 0
let checks = 0
const ok = (cond, msg) => {
checks++
if (cond) console.log(` ok ${msg}`)
else {
failures++
console.error(` FAIL ${msg}`)
}
}

// The header brand span (the studio logo + tagline shared across every page).
// Extract only the tagline inside `.brand-copy` so footer paragraphs and body
// copy cannot mask a regression in the header.
const brandTagline = (html) => {
const match = html.match(
/<span class="brand-copy">[\s\S]*?<span>([\s\S]*?)<\/span>[\s\S]*?<\/span>/
)
return match ? match[1].replace(/\s+/g, " ").trim() : null
}

const STUDIO_TAGLINE = "Products for people and teams"
const APP_TAGLINE = "Independent iPhone apps"

// The 6 studio-level pages brand the whole studio and must match the
// homepage's current positioning (products for people and one sharper
// software system for teams), not the apps-only tagline.
const STUDIO_PAGES = [
"public/support/index.html",
"public/contact/index.html",
"public/privacy/index.html",
"public/privacy-choices/index.html",
"public/terms/index.html",
"public/404.html"
]

// The 6 app pages describe specific apps, where the apps-only tagline is
// accurate.
const APP_PAGES = [
"public/promptly/index.html",
"public/promptly/support/index.html",
"public/promptly/privacy/index.html",
"public/drishti/index.html",
"public/drishti/support/index.html",
"public/drishti/privacy/index.html"
]

console.log("test-public-brand-tagline: every public page's header brand span carries the right studio tagline")

console.log("A. the homepage brand span carries the studio tagline")
const home = read("public/index.html")
ok(brandTagline(home) === STUDIO_TAGLINE, "homepage brand span reads 'Products for people and teams'")

console.log("B. the 6 studio-level pages carry the studio tagline, not the apps-only one")
for (const file of STUDIO_PAGES) {
const html = read(file)
ok(brandTagline(html) === STUDIO_TAGLINE, `${file} brand span reads 'Products for people and teams'`)
ok(!brandTagline(html).includes(APP_TAGLINE), `${file} brand span does not say 'Independent iPhone apps'`)
}

console.log("C. the 6 app pages keep the apps-only tagline")
for (const file of APP_PAGES) {
const html = read(file)
ok(brandTagline(html) === APP_TAGLINE, `${file} brand span reads 'Independent iPhone apps'`)
}

console.log("D. npm test/ci wiring")
const pkg = JSON.parse(read("package.json"))
ok(
pkg.scripts.test.includes("test-public-brand-tagline.mjs"),
"npm test runs the public brand tagline test"
)
ok(
pkg.scripts.ci.includes("test-public-brand-tagline.mjs"),
"npm run ci runs the public brand tagline test"
)

console.log(`\n${checks} checks, ${failures} failures`)
process.exit(failures === 0 ? 0 : 1)