diff --git a/www/README.md b/www/README.md index 0d98a3d..9c47382 100644 --- a/www/README.md +++ b/www/README.md @@ -118,6 +118,7 @@ Astro prints the preview URL, normally `http://localhost:4321`. ```sh npm run build npm run audit:links +npm run audit:images ``` The link audit reads `dist/` after a successful build. If rendered output is @@ -281,6 +282,7 @@ npm run generate:sitemap npm run generate:redirects npm run build npm run audit:links +npm run audit:images ``` Extraction regenerates content files, copied assets, and inventories. Review @@ -332,6 +334,7 @@ Build first: ```sh npm run build npm run audit:links +npm run audit:images ``` ### A content page is missing diff --git a/www/package.json b/www/package.json index 32fad18..342f37e 100644 --- a/www/package.json +++ b/www/package.json @@ -14,6 +14,7 @@ "extract:full": "node tools/extract-site.mjs", "crawl:live": "node tools/crawl-live-site.mjs", "audit:links": "node tools/audit-links.mjs", + "audit:images": "node tools/audit-page-imagery.mjs", "generate:sitemap": "node tools/generate-sitemap.mjs", "generate:redirects": "node tools/generate-redirects.mjs" }, diff --git a/www/public/assets/images/hero-aba-employee-portal.webp b/www/public/assets/images/hero-aba-employee-portal.webp new file mode 100644 index 0000000..00a0074 Binary files /dev/null and b/www/public/assets/images/hero-aba-employee-portal.webp differ diff --git a/www/public/assets/images/hero-aba-therapy-intake-process.webp b/www/public/assets/images/hero-aba-therapy-intake-process.webp new file mode 100644 index 0000000..d2ec564 Binary files /dev/null and b/www/public/assets/images/hero-aba-therapy-intake-process.webp differ diff --git a/www/public/assets/images/hero-about.webp b/www/public/assets/images/hero-about.webp new file mode 100644 index 0000000..c06237f Binary files /dev/null and b/www/public/assets/images/hero-about.webp differ diff --git a/www/public/assets/images/hero-bg-blank.png b/www/public/assets/images/hero-bg-blank.png new file mode 100644 index 0000000..4356397 Binary files /dev/null and b/www/public/assets/images/hero-bg-blank.png differ diff --git a/www/public/assets/images/hero-careers.webp b/www/public/assets/images/hero-careers.webp new file mode 100644 index 0000000..875d738 Binary files /dev/null and b/www/public/assets/images/hero-careers.webp differ diff --git a/www/public/assets/images/hero-client-forms.webp b/www/public/assets/images/hero-client-forms.webp new file mode 100644 index 0000000..e728ad4 Binary files /dev/null and b/www/public/assets/images/hero-client-forms.webp differ diff --git a/www/public/assets/images/hero-contact-aia.webp b/www/public/assets/images/hero-contact-aia.webp new file mode 100644 index 0000000..d12f9a5 Binary files /dev/null and b/www/public/assets/images/hero-contact-aia.webp differ diff --git a/www/public/assets/images/hero-faq.webp b/www/public/assets/images/hero-faq.webp new file mode 100644 index 0000000..e2547a8 Binary files /dev/null and b/www/public/assets/images/hero-faq.webp differ diff --git a/www/public/assets/images/hero-insurance-coverage-guide.webp b/www/public/assets/images/hero-insurance-coverage-guide.webp new file mode 100644 index 0000000..ef7a1c3 Binary files /dev/null and b/www/public/assets/images/hero-insurance-coverage-guide.webp differ diff --git a/www/public/assets/images/hero-library-index.webp b/www/public/assets/images/hero-library-index.webp new file mode 100644 index 0000000..d2ec564 Binary files /dev/null and b/www/public/assets/images/hero-library-index.webp differ diff --git a/www/public/assets/images/hero-meet-the-aia-team.webp b/www/public/assets/images/hero-meet-the-aia-team.webp new file mode 100644 index 0000000..2692e50 Binary files /dev/null and b/www/public/assets/images/hero-meet-the-aia-team.webp differ diff --git a/www/public/assets/images/hero-pediatric-services.webp b/www/public/assets/images/hero-pediatric-services.webp new file mode 100644 index 0000000..e15d382 Binary files /dev/null and b/www/public/assets/images/hero-pediatric-services.webp differ diff --git a/www/public/assets/images/hero-referrals.webp b/www/public/assets/images/hero-referrals.webp new file mode 100644 index 0000000..556df4d Binary files /dev/null and b/www/public/assets/images/hero-referrals.webp differ diff --git a/www/public/assets/images/hero-schedule-aia-tour.webp b/www/public/assets/images/hero-schedule-aia-tour.webp new file mode 100644 index 0000000..b151d8e Binary files /dev/null and b/www/public/assets/images/hero-schedule-aia-tour.webp differ diff --git a/www/public/assets/images/hero-services-behavioral-aba.webp b/www/public/assets/images/hero-services-behavioral-aba.webp new file mode 100644 index 0000000..919a3b2 Binary files /dev/null and b/www/public/assets/images/hero-services-behavioral-aba.webp differ diff --git a/www/public/assets/images/hero-services-psychological.webp b/www/public/assets/images/hero-services-psychological.webp new file mode 100644 index 0000000..ea1b7a6 Binary files /dev/null and b/www/public/assets/images/hero-services-psychological.webp differ diff --git a/www/public/assets/images/hero-services-sociological.webp b/www/public/assets/images/hero-services-sociological.webp new file mode 100644 index 0000000..c043fb8 Binary files /dev/null and b/www/public/assets/images/hero-services-sociological.webp differ diff --git a/www/public/assets/images/hero-ways-to-giveback.webp b/www/public/assets/images/hero-ways-to-giveback.webp new file mode 100644 index 0000000..4ecbb92 Binary files /dev/null and b/www/public/assets/images/hero-ways-to-giveback.webp differ diff --git a/www/reports/asset-inventory.csv b/www/reports/asset-inventory.csv index 73c678f..14942e1 100644 --- a/www/reports/asset-inventory.csv +++ b/www/reports/asset-inventory.csv @@ -170,3 +170,21 @@ source,target,size,kind "hubfs/team-timirah-clay.webp","public/assets/images/team-timirah-clay.webp","16496","images" "hubfs/toddler-bcba-support.webp","public/assets/images/toddler-bcba-support.webp","11182","images" "hubfs/united-healthcare-logo-1.webp","public/assets/images/united-healthcare-logo-1.webp","4368","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-aba-therapy-intake-process.webp","public/assets/images/hero-aba-therapy-intake-process.webp","14392","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-services-behavioral-aba.webp","public/assets/images/hero-services-behavioral-aba.webp","15330","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-about.webp","public/assets/images/hero-about.webp","24764","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-services-psychological.webp","public/assets/images/hero-services-psychological.webp","15490","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-careers.webp","public/assets/images/hero-careers.webp","24728","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-bg-blank.png","public/assets/images/hero-bg-blank.png","41772","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-client-forms.webp","public/assets/images/hero-client-forms.webp","13878","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-contact-aia.webp","public/assets/images/hero-contact-aia.webp","20230","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-ways-to-giveback.webp","public/assets/images/hero-ways-to-giveback.webp","11654","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-aba-employee-portal.webp","public/assets/images/hero-aba-employee-portal.webp","19798","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-faq.webp","public/assets/images/hero-faq.webp","14624","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-insurance-coverage-guide.webp","public/assets/images/hero-insurance-coverage-guide.webp","21624","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-services-sociological.webp","public/assets/images/hero-services-sociological.webp","16046","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-referrals.webp","public/assets/images/hero-referrals.webp","16646","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-pediatric-services.webp","public/assets/images/hero-pediatric-services.webp","18120","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-meet-the-aia-team.webp","public/assets/images/hero-meet-the-aia-team.webp","15310","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-schedule-aia-tour.webp","public/assets/images/hero-schedule-aia-tour.webp","13290","images" +"live:https://www.azinstitute4autism.com/hubfs/hero-library-index.webp","public/assets/images/hero-library-index.webp","14392","images" diff --git a/www/reports/cleanup-log.md b/www/reports/cleanup-log.md index 6fdd7dc..69230a7 100644 --- a/www/reports/cleanup-log.md +++ b/www/reports/cleanup-log.md @@ -22,5 +22,10 @@ - Repaired mirror-rewritten PDF, lightbox, CTA, and relative content links. - Limited language-switcher choices to translations that have generated routes. - Verified and implemented the current production likes/views API contract. +- Recovered 18 live page-banner assets that the wget mirror missed because + HubSpot injected them through malformed inline `background-image` styles. +- Restored the live library banner and consultation form section background. +- Added a mapped-page-imagery audit to prevent missing visual assets from + silently passing the source link audit. - Added language-qualified content collection IDs to prevent English, Spanish, and Arabic entries with the same slug from overwriting each other. diff --git a/www/reports/migration-summary.md b/www/reports/migration-summary.md index 0d402e2..82dfbb2 100644 --- a/www/reports/migration-summary.md +++ b/www/reports/migration-summary.md @@ -12,7 +12,7 @@ family, team page, library indexes, and blog-post family. - 46 English, 12 Spanish, and 7 Arabic library posts. - 21 English, 9 Spanish, and 2 Arabic page records. - One author record per language. -- 149 self-hosted images, 20 font files, and two PDF downloads. +- 167 self-hosted images, 20 font files, and two PDF downloads. - Current June and May 2026 English library articles are included. The raw mirror remains untouched. HubSpot-generated wrappers, analytics, @@ -37,6 +37,9 @@ Implemented fidelity work includes: order using one reusable Astro component and self-hosted source assets. - Rebuilt service pages around the live compact title banner and editorial presentation, with current visible headings and working calls to action. +- Recovered and restored the live decorative hero imagery for all mapped + English and Spanish page routes plus every language's library index. +- Restored the consultation form section's injected background image. - Added a dedicated live-derived team card grid rather than presenting the extracted team content as a generic article. - Rebuilt library indexes and blog-post presentation around the live sidebar, @@ -109,6 +112,8 @@ unavailable. - `npm run audit:links`: passed with zero broken internal source links. The audit now checks generated routes, root-relative references, relative Markdown links, and public assets when rendered output is unavailable. +- `npm run audit:images`: passed with no missing mapped page banners, section + backgrounds, or blog featured images. - `npm run generate:sitemap`: passed; generated 97 URLs. - `npm run generate:redirects`: passed. - All migration `.mjs` tools and the sandbox DNS helper pass `node --check`. diff --git a/www/reports/page-imagery-audit.md b/www/reports/page-imagery-audit.md new file mode 100644 index 0000000..51c4f27 --- /dev/null +++ b/www/reports/page-imagery-audit.md @@ -0,0 +1,5 @@ +# Page Imagery Audit + +Checked 84 page-banner, section-background, and blog-featured-image references. + +No missing mapped page imagery was detected. diff --git a/www/src/components/FormShell.astro b/www/src/components/FormShell.astro index 81f291b..5b5af5d 100644 --- a/www/src/components/FormShell.astro +++ b/www/src/components/FormShell.astro @@ -1,7 +1,7 @@ --- -const { title = 'Schedule Your Free Consultation' } = Astro.props; +const { title = 'Schedule Your Free Consultation', showBackground = false } = Astro.props; --- -
+

Get started

{title}

Tell our client advocates how we can help. Submission is disabled until a production form backend is selected.

diff --git a/www/src/data/page-visuals.ts b/www/src/data/page-visuals.ts new file mode 100644 index 0000000..0ede70e --- /dev/null +++ b/www/src/data/page-visuals.ts @@ -0,0 +1,20 @@ +export const pageHeroImages: Record = { + 'aba-therapy-intake-process': '/assets/images/hero-aba-therapy-intake-process.webp', + 'aba-therapy': '/assets/images/hero-services-behavioral-aba.webp', + about: '/assets/images/hero-about.webp', + 'autism-evaluations': '/assets/images/hero-services-psychological.webp', + careers: '/assets/images/hero-careers.webp', + 'client-consultation': '/assets/images/hero-bg-blank.png', + 'client-forms': '/assets/images/hero-client-forms.webp', + contact: '/assets/images/hero-contact-aia.webp', + 'donate-autism-giveback': '/assets/images/hero-ways-to-giveback.webp', + 'employee-portal': '/assets/images/hero-aba-employee-portal.webp', + faqs: '/assets/images/hero-faq.webp', + insurance: '/assets/images/hero-insurance-coverage-guide.webp', + 'learner-social-club': '/assets/images/hero-services-sociological.webp', + 'privacy-policy': '/assets/images/hero-bg-blank.png', + referrals: '/assets/images/hero-referrals.webp', + services: '/assets/images/hero-pediatric-services.webp', + team: '/assets/images/hero-meet-the-aia-team.webp', + tour: '/assets/images/hero-schedule-aia-tour.webp' +}; diff --git a/www/src/layouts/BlogIndexLayout.astro b/www/src/layouts/BlogIndexLayout.astro index 3c183f2..b9b0e21 100644 --- a/www/src/layouts/BlogIndexLayout.astro +++ b/www/src/layouts/BlogIndexLayout.astro @@ -5,7 +5,7 @@ const languagePrefix = lang === 'en' ? '' : `/${lang}`; const canonical = `https://www.azinstitute4autism.com${languagePrefix}/library`; --- -

Welcome to

{title}

+

Welcome to

{title}

Library

{description}

diff --git a/www/src/layouts/PageLayout.astro b/www/src/layouts/PageLayout.astro index e1a69a1..5c08c17 100644 --- a/www/src/layouts/PageLayout.astro +++ b/www/src/layouts/PageLayout.astro @@ -2,6 +2,7 @@ import BaseLayout from './BaseLayout.astro'; import FormShell from '../components/FormShell.astro'; import TeamPage from '../components/TeamPage.astro'; +import { pageHeroImages } from '../data/page-visuals'; const { entry } = Astro.props; const showForm = ['client-consultation', 'contact', 'schedule-consultation', 'referrals'].includes(entry.data.slug); const serviceTitles: Record> = { @@ -44,13 +45,14 @@ const pageTitles: Record> = { }; const bannerTitle = serviceTitles[entry.data.lang]?.[entry.data.slug] || pageTitles[entry.data.lang]?.[entry.data.slug] || entry.data.title.split('|')[0].trim(); const isService = Boolean(serviceTitles[entry.data.lang]?.[entry.data.slug]); +const heroImage = pageHeroImages[entry.data.slug]; --- - -
+ +

{bannerTitle}

{entry.data.slug === 'team' && entry.data.lang === 'en' ? :
} - {showForm && } + {showForm && }
diff --git a/www/src/styles/components.css b/www/src/styles/components.css index 41b1794..dc53f1a 100644 --- a/www/src/styles/components.css +++ b/www/src/styles/components.css @@ -54,8 +54,10 @@ .faq summary { cursor: pointer; font-weight: 700; } .source-page-banner { background: var(--color-tint); padding-block: 4rem; text-align: center; } .source-page-banner h1 { margin: 0; } -.service-banner { background-color: #e8f1ee; background-image: radial-gradient(circle at 14% 45%, rgb(37 64 128 / 9%) 0 54px, transparent 55px), radial-gradient(circle at 28% 25%, rgb(37 64 128 / 10%) 0 22px, transparent 23px), radial-gradient(circle at 74% 50%, rgb(37 64 128 / 8%) 0 42px, transparent 43px); padding-block: 7rem; } -.library-banner { background: var(--color-tint); padding-block: 5rem; text-align: center; } +.source-page-banner.has-source-image { background-color: var(--color-tint); background-position: center; background-repeat: no-repeat; background-size: cover; padding-block: 10rem; text-align: left; } +.source-page-banner.has-source-image h1 { max-width: 600px; } +.library-banner { background-color: var(--color-tint); background-image: url('/assets/images/hero-library-index.webp'); background-position: center; background-repeat: no-repeat; background-size: cover; padding-block: 10rem; text-align: left; } +.library-banner-copy { max-width: 600px; } .library-banner h1 { margin: 0; } .library-intro { background: var(--color-primary); color: white; padding-block: 3rem; } .library-intro h2 { color: white; } @@ -140,5 +142,7 @@ .blog-list .blog-card { grid-template-columns: 1fr; } .article-featured { height: auto; } .team-grid { grid-template-columns: 1fr; } + .source-page-banner.has-source-image, .library-banner { padding-block: 6.25rem; text-align: center; } + .source-page-banner.has-source-image h1, .library-banner-copy { margin-inline: auto; } } @media (min-width: 761px) and (max-width: 1050px) { .team-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } } diff --git a/www/src/styles/forms.css b/www/src/styles/forms.css index 226a2a5..8f079e8 100644 --- a/www/src/styles/forms.css +++ b/www/src/styles/forms.css @@ -1,4 +1,5 @@ .form-section { background: var(--color-tint); padding-block: var(--space-xl); } +.form-section.form-section-background { background-image: url('/assets/images/rbt-toddler-play.webp'); background-position: center bottom; background-repeat: no-repeat; background-size: contain; } .form-grid { display: grid; gap: var(--space-xl); grid-template-columns: .8fr 1.2fr; } .form { background: white; border-radius: var(--radius-md); box-shadow: var(--shadow-sm); display: grid; gap: var(--space-md); padding: var(--space-lg); } .form label { display: grid; font-weight: 700; gap: var(--space-xs); } diff --git a/www/tools/audit-page-imagery.mjs b/www/tools/audit-page-imagery.mjs new file mode 100644 index 0000000..373fbc8 --- /dev/null +++ b/www/tools/audit-page-imagery.mjs @@ -0,0 +1,46 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import fg from 'fast-glob'; +import matter from 'gray-matter'; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const publicRoot = path.join(root, 'public'); +const failures = []; +const checked = []; + +async function checkAsset(reference, owner) { + if (!reference?.startsWith('/assets/')) return; + const target = path.join(publicRoot, reference); + const exists = await fs.access(target).then(() => true).catch(() => false); + checked.push({ owner, reference, exists }); + if (!exists) failures.push(`${owner}: ${reference}`); +} + +const visualSource = await fs.readFile(path.join(root, 'src/data/page-visuals.ts'), 'utf8'); +for (const match of visualSource.matchAll(/['"](?\/assets\/images\/[^'"]+)['"]/g)) { + await checkAsset(match.groups.reference, 'page hero mapping'); +} +await checkAsset('/assets/images/hero-library-index.webp', 'library banner'); +await checkAsset('/assets/images/rbt-toddler-play.webp', 'consultation form background'); + +for (const file of await fg('src/content/blog/**/*.{md,mdx}', { cwd: root, absolute: true })) { + const { data } = matter(await fs.readFile(file, 'utf8')); + if (!data.draft) await checkAsset(data.featuredImage, path.relative(root, file)); +} + +const uniqueChecked = new Map(checked.map((item) => [`${item.owner}:${item.reference}`, item])); +const report = [ + '# Page Imagery Audit', + '', + `Checked ${uniqueChecked.size} page-banner, section-background, and blog-featured-image references.`, + '', + failures.length + ? `## Missing Assets\n\n${failures.map((item) => `- ${item}`).join('\n')}` + : 'No missing mapped page imagery was detected.', + '' +].join('\n'); + +await fs.writeFile(path.join(root, 'reports/page-imagery-audit.md'), report); +console.log(`${failures.length} missing mapped page images.`); +if (failures.length) process.exitCode = 1;