# MIGRATION_BRIEF.md ## Authority and interpretation Read and follow `AGENTS.md` first. It is the authoritative project policy; this brief provides detailed implementation guidance. If any wording here appears to conflict with `AGENTS.md`, follow `AGENTS.md` and correct this brief before continuing. This is a fidelity-first migration, not a redesign. The raw mirror is a convenient local extraction and inspection aid, but the live public site is the single content and visual source of truth. The `migration-foundation` branch may be consulted for nonvisual tooling and recovered content, but it must not be used as the visual baseline. ## Task Migrate the public Arizona Institute for Autism website from a mirrored HubSpot-generated static copy into a clean, maintainable Astro + TypeScript site. Raw mirrored source: ```txt ./www.azinstitute4autism.com ``` New Astro project target: ```txt ./www ``` The raw mirror was created with: ```sh wget --mirror --page-requisites --adjust-extension --convert-links --no-parent https://www.azinstitute4autism.com ``` There is no HubSpot export, no HubSpot CLI access, and no HubSpot API access. Use the live public website as the single source of truth: ```txt https://www.azinstitute4autism.com ``` Use the local mirror as a convenient extraction and inspection aid. It may contain stale, missing, rewritten, or incorrectly downloaded content and assets. Verify content, design, URLs, metadata, assets, and responsive behavior against the live site. When the live site and mirror disagree, follow the live site and document material discrepancies. If the live site is temporarily unavailable, work that depends on its authority must remain explicitly unverified rather than silently treating the mirror as authoritative. ## High-level goal Create a new Astro site in `./www` that is: - Astro-based - TypeScript-based - static-hosting friendly - Markdown-first - MDX-enabled only when needed - Front Matter CMS friendly - multilingual for English, Arabic, and Spanish - self-hosted for media and assets wherever practical - SEO-conscious - accessible - maintainable - faithful to the current design, layout, and responsive behavior - free of unnecessary HubSpot-generated structure - prepared for future development and publishing ## Important constraints Do not modify or delete: ```txt ./www.azinstitute4autism.com ``` Do not depend on: - HubSpot CLI - HubSpot API - HubSpot export files - a database - a form backend - a headless CMS - Tailwind Do not hardcode environment-specific deployment assumptions. Hosting is undecided. Possible future hosts include: - Netlify - nginx - Cloudflare Pages - Vercel - another static host Use `npm`, not pnpm or yarn. Use plain CSS with design tokens. Use Astro image optimization where useful. Generate nginx rewrite rules for changed URLs. ## Current known requirements ### URL preservation Preserve existing URL structure exactly whenever possible. Important paths include: ```txt / /aba /autismevaluations /learnersocialclub /client-consultation /library /library/post-slug ``` If a URL must change, document it and generate an nginx rewrite. Do not generate redirects for URLs that remain unchanged. ### Content format Use file-based Markdown as the default content format. Use `.md` for most pages and blog posts. Use `.mdx` only when embedded Astro/React-style components are genuinely needed. ### Front Matter CMS The content structure should work well with the Front Matter CMS VS Code extension. Create a `frontmatter.json` file at the Astro project root. ### Forms Recreate visible forms as styled static HTML. Do not implement backend submission. Each form must include TODO comments. Example: ```html
``` If original HubSpot form fields cannot be fully recovered, create a reasonable static approximation and document the uncertainty. ### Likes and views Preserve the like/view counter conceptually. Known production API base: ```txt https://api.azinstitute4autism.com ``` Use environment configuration: ```txt PUBLIC_AIA_API_BASE=https://api.azinstitute4autism.com ``` Add this to `.env.example`. Do not make the build fail if the API is unavailable. The like/view feature should degrade gracefully. ### Multilingual Support: - English - Arabic - Spanish English is the default. Use these URL patterns: ```txt English: / /aba /autismevaluations /library/post-slug Arabic: /ar /ar/aba /ar/autismevaluations /ar/library/post-slug Spanish: /es /es/aba /es/autismevaluations /es/library/post-slug ``` Arabic pages must use RTL layout. Arabic HTML: ```html ``` English HTML: ```html ``` Spanish HTML: ```html ``` Add: ```txt src/styles/rtl.css ``` If Arabic or Spanish source content is missing, create minimal placeholder content only where needed to demonstrate the structure. Mark placeholders clearly: ```md ``` Do not invent extensive translations. ### Design direction The new site must faithfully reproduce the live public site's visible design, layout, content hierarchy, and responsive behavior. Do not redesign, reinterpret, modernize, simplify, or genericize source pages. Preserve typography, colors, backgrounds, spacing, proportions, imagery, section order, decorative treatments, navigation, calls to action, forms, and page-specific distinctions. Reuse exact source assets and fonts wherever practical. Do not copy HubSpot-generated DOM or CSS wholesale. Refactor genuinely repeated sections into reusable components. Do not force distinctive source sections into generic components when doing so changes their appearance or structure. Use semantic markup. Use plain CSS with design tokens. Do not use Tailwind. ### Fidelity workflow For each page family or shared component: 1. Inspect the live page, HTML, CSS, assets, and responsive behavior. 2. Use the mirror to accelerate local extraction and inspection. 3. Resolve discrepancies in favor of the live public site. 4. Record important visual details and identify genuine shared patterns. 5. Implement the page or component in maintainable Astro code. 6. Compare the complete rendered page with the live public site at representative desktop and mobile viewport widths. 7. Fix material visual differences before marking it complete. Document intentional visual deviations and their reasons in `reports/migration-summary.md`. ## Required target structure Create this project structure in `./www`: ```txt www/ README.md package.json astro.config.mjs tsconfig.json .env.example frontmatter.json public/ assets/ images/ fonts/ media/ downloads/ robots.txt sitemap.xml src/ assets/ images/ components/ Header.astro Footer.astro MainNav.astro MobileNav.astro LanguageSwitcher.astro Hero.astro ServiceCard.astro BlogCard.astro ConsultationCTA.astro InsuranceStrip.astro LocationCard.astro FAQAccordion.astro LikeViewCounter.astro Seo.astro FormShell.astro content/ config.ts pages/ en/ ar/ es/ blog/ en/ ar/ es/ authors/ en/ ar/ es/ data/ navigation.en.json navigation.ar.json navigation.es.json site.json redirects.json services.json layouts/ BaseLayout.astro PageLayout.astro BlogPostLayout.astro BlogIndexLayout.astro pages/ index.astro aba.astro autismevaluations.astro learnersocialclub.astro client-consultation.astro ar/ index.astro [...slug].astro es/ index.astro [...slug].astro library/ index.astro [slug].astro page/ [page].astro scripts/ forms.ts navigation.ts likes-views.ts styles/ global.css variables.css typography.css layout.css components.css forms.css blog.css rtl.css tools/ extract-site.mjs crawl-live-site.mjs audit-links.mjs generate-redirects.mjs generate-sitemap.mjs original/ README.md reports/ url-inventory.csv asset-inventory.csv seo-audit.md accessibility-audit.md broken-links.md cleanup-log.md redirect-map.csv nginx-rewrites.conf migration-summary.md ``` The `original/README.md` file should explain that the raw source mirror lives outside the Astro project at: ```txt ../www.azinstitute4autism.com ``` Do not duplicate the entire raw mirror inside `./www` unless there is a specific reason. ## Initial inspection Before creating or modifying files, inspect the mirror. Look for: - all HTML files - URL paths - CSS files - JS files - image assets - SVGs - fonts - PDFs - media files - blog posts - blog listing pages - blog pagination - author pages - Arabic pages - Spanish pages - sitemap files - robots.txt - canonical tags - Open Graph metadata - schema/JSON-LD - forms - navigation - footer links - HubSpot-specific scripts - analytics/pixel scripts - like/view counter code - broken or rewritten local links - asset references still pointing to remote hosts Create an initial implementation plan after inspection. ## Astro setup Create or scaffold the Astro project in: ```txt ./www ``` Use: ```sh npm create astro@latest www ``` Adjust as needed. Install and configure only useful dependencies. Likely useful dependencies: ```txt astro @astrojs/mdx @astrojs/sitemap typescript zod cheerio fast-glob gray-matter turndown ``` Use judgment. Avoid unnecessary framework bloat. The final project should support: - Astro - TypeScript - Markdown content collections - MDX integration - sitemap generation - image optimization - plain CSS imports - Front Matter CMS editing ## Content collections Create: ```txt src/content/config.ts ``` Define collections for: - pages - blog - authors Use Zod schemas. ### Blog schema Recommended fields: ```ts title: string description: string slug: string date: Date updatedDate?: Date author: string category?: string tags?: string[] featuredImage?: string alt?: string canonical?: string draft?: boolean lang: 'en' | 'ar' | 'es' translationKey?: string ``` ### Page schema Recommended fields: ```ts title: string description: string slug: string canonical?: string featuredImage?: string alt?: string lang: 'en' | 'ar' | 'es' translationKey?: string draft?: boolean ``` ### Author schema Recommended fields: ```ts name: string slug: string description?: string avatar?: string lang: 'en' | 'ar' | 'es' translationKey?: string ``` ### Example blog post ```md --- title: "ABA Prompting: A Parent-Friendly Guide" description: "Learn how ABA prompting helps children build independence through clear support and gradual fading." slug: "aba-prompting" date: "2026-05-29" author: "aia" category: "ABA Therapy" tags: - ABA therapy - autism parenting featuredImage: "/assets/images/blog/aba-prompting.webp" alt: "Parent helping a child practice brushing teeth with gentle hand support" canonical: "https://www.azinstitute4autism.com/library/aba-prompting" draft: false lang: "en" translationKey: "aba-prompting" --- Article content goes here. ``` ## Front Matter CMS configuration Create: ```txt frontmatter.json ``` Configure it for the VS Code Front Matter CMS extension. Register these content folders: ```txt src/content/pages/en src/content/pages/ar src/content/pages/es src/content/blog/en src/content/blog/ar src/content/blog/es src/content/authors/en src/content/authors/ar src/content/authors/es ``` Configure content types: - page - blog - author Use field names aligned with Astro content schemas. Useful fields: - title - description - slug - date - updatedDate - author - category - tags - featuredImage - alt - canonical - draft - lang - translationKey Choice fields: ```txt lang: en, ar, es draft: true, false ``` Make images selectable from: ```txt public/assets/images src/assets/images ``` ## Design system Create: ```txt src/styles/variables.css src/styles/typography.css src/styles/layout.css src/styles/components.css src/styles/forms.css src/styles/blog.css src/styles/rtl.css src/styles/global.css ``` Extract the current site's visual language from the live public site, using the mirrored CSS and HTML as a convenient local aid after checking for discrepancies. Tokens must encode source values; they must not introduce a replacement visual system. Use design tokens such as: ```css :root { --color-primary: ; --color-primary-dark: ; --color-secondary: ; --color-accent: ; --color-background: ; --color-surface: ; --color-text: ; --color-muted: ; --color-border: ; --font-sans: ; --font-heading: ; --space-xs: ; --space-sm: ; --space-md: ; --space-lg: ; --space-xl: ; --radius-sm: ; --radius-md: ; --radius-lg: ; --shadow-sm: ; --shadow-md: ; --container: ; } ``` Document assumptions in: ```txt reports/cleanup-log.md ``` ## Components Create reusable Astro components. Required components: ```txt Header.astro Footer.astro MainNav.astro MobileNav.astro LanguageSwitcher.astro Hero.astro ServiceCard.astro BlogCard.astro ConsultationCTA.astro InsuranceStrip.astro LocationCard.astro FAQAccordion.astro LikeViewCounter.astro Seo.astro FormShell.astro ``` Header and footer should be driven by JSON files in: ```txt src/data/ ``` Do not hardcode navigation in multiple templates. ## Data files Create: ```txt src/data/navigation.en.json src/data/navigation.ar.json src/data/navigation.es.json src/data/site.json src/data/redirects.json src/data/services.json ``` Navigation should include primary and footer sections. Example: ```json { "primary": [ { "label": "ABA Therapy", "href": "/aba" }, { "label": "Autism Evaluations", "href": "/autismevaluations" }, { "label": "Learner Social Club", "href": "/learnersocialclub" }, { "label": "Library", "href": "/library" }, { "label": "Contact", "href": "/client-consultation" } ] } ``` ## Layouts Create: ```txt src/layouts/BaseLayout.astro src/layouts/PageLayout.astro src/layouts/BlogPostLayout.astro src/layouts/BlogIndexLayout.astro ``` `BaseLayout.astro` should include: - HTML `lang` - HTML `dir` - SEO component - global styles - header - main slot - footer - scripts as needed ## SEO component Create: ```txt src/components/Seo.astro ``` It should support: - title - description - canonical - Open Graph tags - Twitter card tags - image - noindex for drafts/placeholders - language - direction - hreflang links where translation relationships are known - JSON-LD/schema when extracted Preserve metadata from the mirror wherever possible. Generate: ```txt public/sitemap.xml public/robots.txt reports/seo-audit.md ``` The SEO audit should include: - URL - old title - new title - old description - new description - canonical - H1 - notes - missing metadata ## Routes Create route files for English primary pages: ```txt src/pages/index.astro src/pages/aba.astro src/pages/autismevaluations.astro src/pages/learnersocialclub.astro src/pages/client-consultation.astro ``` Create blog routes: ```txt src/pages/library/index.astro src/pages/library/[slug].astro src/pages/library/page/[page].astro ``` Create multilingual catch-all routes: ```txt src/pages/ar/index.astro src/pages/ar/[...slug].astro src/pages/es/index.astro src/pages/es/[...slug].astro ``` Implement routing in a clean, maintainable way. ## Extraction scripts Create: ```txt tools/extract-site.mjs tools/crawl-live-site.mjs tools/audit-links.mjs tools/generate-redirects.mjs tools/generate-sitemap.mjs ``` ### `extract-site.mjs` This script should: - scan the mirror - identify HTML files - infer URL paths - identify page type - identify blog posts - identify listing pages - extract title/meta/H1/body/main content - extract canonical and Open Graph metadata - extract schema/JSON-LD where present - convert blog posts to Markdown where feasible - create page Markdown where useful - copy/normalize assets - rewrite local asset references - create initial reports The script does not need to be perfect, but it should be useful and documented. ### `crawl-live-site.mjs` This script should: - attempt to crawl the live site if internet is available - discover URLs from sitemap and internal links - compare discovered URLs against the mirror - document missing URLs/assets - avoid aggressive crawling - respect the scope of `www.azinstitute4autism.com` ### `audit-links.mjs` This script should: - inspect generated content and/or built output - identify internal links that do not resolve - identify external links if easy to check - produce: ```txt reports/broken-links.md ``` ### `generate-redirects.mjs` This script should: - read URL inventory and redirect map - generate nginx rewrite rules - output: ```txt reports/nginx-rewrites.conf ``` Use this style: ```nginx rewrite ^/old-path/?$ /new-path permanent; ``` ### `generate-sitemap.mjs` This script should: - generate or validate sitemap output - include language routes where appropriate - avoid drafts/placeholders if marked noindex ## Asset handling Extract/download/self-host assets into: ```txt public/assets/ src/assets/ ``` Use `public/assets` for assets referenced directly in Markdown/frontmatter. Use `src/assets` for component-imported assets and Astro optimization. Organize: ```txt public/assets/images/ public/assets/fonts/ public/assets/media/ public/assets/downloads/ ``` Normalize filenames where practical: ```txt hero-home.webp aba-therapy-child-session.webp blog-autism-play.webp aia-logo.svg ``` Do not destroy originals unless they are duplicated and unused. Create: ```txt reports/asset-inventory.csv ``` Include: - original URL/path - new path - file type - used by - notes ## Forms Recreate visible forms as styled HTML forms. Do not implement backend behavior. Use `FormShell.astro` where useful. Each form must include TODO comments. Example: ```html ``` Document form assumptions and missing backend work in: ```txt reports/migration-summary.md ``` ## Like/view counter Create: ```txt src/components/LikeViewCounter.astro src/scripts/likes-views.ts ``` Use: ```txt PUBLIC_AIA_API_BASE=https://api.azinstitute4autism.com ``` Add `.env.example`: ```txt PUBLIC_AIA_API_BASE=https://api.azinstitute4autism.com ``` The frontend should: - fetch counts when possible - allow like/unlike behavior if the existing API supports it - not break the page when the API is unavailable - avoid blocking static builds - document any uncertainty in the migration summary ## Accessibility Improve obvious accessibility issues while preserving the design. Check for: - missing alt text - multiple H1s - skipped heading levels - unlabeled form fields - low-contrast text - missing button labels - empty links - keyboard navigation issues - missing nav labels - mobile menu accessibility - language and direction attributes Create: ```txt reports/accessibility-audit.md ``` ## Reports Create all of these: ```txt reports/url-inventory.csv reports/asset-inventory.csv reports/seo-audit.md reports/accessibility-audit.md reports/broken-links.md reports/cleanup-log.md reports/redirect-map.csv reports/nginx-rewrites.conf reports/migration-summary.md ``` ### `migration-summary.md` Include: - what was successfully migrated - what was approximated - what requires manual review - pages migrated - blog posts migrated - media copied - external dependencies remaining - forms requiring backend integration - multilingual placeholder status - SEO issues found - accessibility issues found - broken links - build results - recommended next steps ## Package scripts Add scripts similar to: ```json { "scripts": { "dev": "astro dev", "build": "astro check && astro build", "preview": "astro preview", "extract": "node tools/extract-site.mjs", "crawl": "node tools/crawl-live-site.mjs", "audit:links": "node tools/audit-links.mjs", "generate:sitemap": "node tools/generate-sitemap.mjs", "generate:redirects": "node tools/generate-redirects.mjs" } } ``` If `astro check` requires an additional package, install/configure the needed package or adjust the script appropriately. ## README Create: ```txt www/README.md ``` It should explain: - what the project is - where the raw mirror lives - how the migration was performed - how to install dependencies - how to run local dev - how to build - how to preview - how to add a blog post - how to add a page - how to add an Arabic translation - how to add a Spanish translation - how to edit navigation - how to configure the likes/views API base URL - how forms are currently handled - where reports live - how to review nginx rewrites Include: ```sh npm install npm run dev npm run build npm run preview ``` ## Build and validation After implementation, run: ```sh npm install npm run build npm run audit:links ``` Fix errors when practical. If something cannot be completed, document it in: ```txt reports/migration-summary.md ``` ## Acceptance criteria The migration is successful when: - `./www` contains a working Astro project - `npm run build` succeeds or unresolved build issues are clearly documented - main public pages render locally - main public pages have been compared with the live site at desktop and mobile widths and have no undocumented material visual differences - blog posts are migrated into file-based Markdown where feasible - Markdown files work with Front Matter CMS - MDX is available but not overused - media is self-hosted wherever practical - current URL paths are preserved wherever possible - nginx rewrite rules are generated for changed paths - forms are styled and marked with TODO backend comments - the like/view counter is isolated and environment-configured - English, Arabic, and Spanish structure exists - Arabic RTL support exists - CSS is organized into design-token-based plain CSS files - reusable Astro components exist - SEO metadata is preserved or documented - audit/report files exist - README explains how to continue development ## Working order Proceed methodically: 1. Read `AGENTS.md`. 2. Read `CLAUDE.md`, if using Claude Code. 3. Read this `MIGRATION_BRIEF.md`. 4. Inspect the live public site. 5. Inspect `./www.azinstitute4autism.com` and identify relevant discrepancies. 6. Summarize a concise implementation plan. 7. Scaffold Astro in `./www`. 8. Build extraction/reporting scripts. 9. Extract pages, blog posts, assets, metadata, navigation, and forms. 10. Refactor repeated sections into Astro components. 11. Configure content collections and Front Matter CMS. 12. Add multilingual structure. 13. Add SEO, sitemap, robots, and redirects. 14. Add reports. 15. Run build and audits. 16. Fix errors. 17. Summarize what changed and what still needs manual review. Prioritize visual fidelity and content correctness while implementing them with clean, maintainable Astro code. Do not trade away visible source design for a generic foundation, and do not copy HubSpot-generated implementation merely to obtain fidelity.