Compare commits

Author SHA1 Message Date
DeCentN2Madness aebd53639a feat(brand): add and switch to cog favicon 2026-07-01 13:54:03 -07:00
DeCentN2Madness bf3d39a643 chore(docs): remove local mirror references, use live site only
Deleted the www.azinstitute4autism.com mirror directory and scrubbed all
references to it from AGENTS.md, MIGRATION_BRIEF.md, www/README.md, and
www/original/README.md. The live public site is now the sole source of
truth with no local mirror fallback.
2026-06-30 20:52:03 -07:00
DeCentN2Madness 664d749439 feat(component): add email obfuscation component 2026-06-30 20:21:33 -07:00
479 changed files with 4580 additions and 104021 deletions

No files matched your search

+2 -2
View File
@@ -59,5 +59,5 @@ temp/
Thumbs.db
Desktop.ini
# Private portal collection, mappings and ciphertext; never a public asset source.
/www/private/employee-portal/
# Read-only wget mirror used as migration source material
/www.azinstitute4autism.com/
-29
View File
@@ -82,35 +82,6 @@ sandboxed command-line tools may fail HTTPS certificate verification. Do not
disable certificate verification for package installation or sensitive
retrievals; use live web search or review the retrieval from the host instead.
## Optional local browser environment
The repository now provides a Linux-only `browser` development shell, separate
from the default content-editing shell. In a normal host terminal, from the
repository root:
```sh
nix --extra-experimental-features "nix-command flakes" develop .#browser
```
It supplies a lockfile-matched Playwright driver, Chromium, headless shell and
font configuration. New processes launched inside this shell inherit
`PLAYWRIGHT_MODULE` and `PLAYWRIGHT_BROWSERS_PATH`; existing sessions do not.
For a guarded real-page smoke test, run from `www`:
```sh
TMPDIR=/tmp npm run build
TMPDIR=/tmp node tools/playwright-smoke.mjs
```
Preview and browser run in the same process environment, avoiding dependence on
remote MCP transport or cross-execution loopback access. All non-loopback and
non-GET/HEAD browser requests are blocked. Results/screenshots stay in `/tmp`.
The tool does not grant access to files or sockets denied by the autonomous
profile. If Nix realization, Chromium startup or loopback access is denied, keep
that result as an environment limitation and use the normal host terminal;
do not weaken TLS, identity, signing or sandbox configuration. No global MCP
configuration or launcher permissions were changed for this setup.
## Git limitation
Codex always protects `.git` recursively in its `workspace-write` sandbox.
+26 -2
View File
@@ -383,6 +383,7 @@ www/
rtl.css
tools/
extract-site.mjs
crawl-live-site.mjs
audit-links.mjs
generate-redirects.mjs
@@ -855,17 +856,39 @@ src/pages/es/[...slug].astro
Implement routing in a clean, maintainable way.
## Migration utility scripts
## 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 available source and generated output
- 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:
@@ -875,7 +898,7 @@ This script should:
- compare discovered URLs against the current site source and generated output
- document missing URLs/assets
- avoid aggressive crawling
- respect the live-site scope
- respect the scope of `www.azinstitute4autism.com`
### `audit-links.mjs`
@@ -1086,6 +1109,7 @@ Add scripts similar to:
"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",
Generated
+8 -10
View File
@@ -2,18 +2,16 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1785090369,
"narHash": "sha256-m0pDuRJG7EDo9ri+4Ksu83VsI+PlxNC9lNBfydejce4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "624af665418d3c65d544145b4d34ad696439570e",
"type": "github"
"lastModified": 1728018373,
"narHash": "sha256-NOiTvBbRLIOe5F6RbHaAh6++BNjsb149fGZd1T4+KBg=",
"rev": "bc947f541ae55e999ffdb4013441347d83b00feb",
"revCount": 688563,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.688563%2Brev-bc947f541ae55e999ffdb4013441347d83b00feb/01925b66-3b70-71bd-b277-924a6c208ba7/source.tar.gz"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
"type": "tarball",
"url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz"
}
},
"root": {
+20 -54
View File
@@ -1,63 +1,29 @@
{
description = "Arizona Institute for Autism Astro development environment";
description = "A Nix-flake-based Node.js development environment";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1.*.tar.gz";
outputs =
{ nixpkgs, ... }:
outputs = { self, nixpkgs }:
let
supportedSystems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
];
forAllSystems =
function: nixpkgs.lib.genAttrs supportedSystems (system: function nixpkgs.legacyPackages.${system});
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit system; overlays = [ self.overlays.default ]; };
});
in
{
devShells = forAllSystems (
pkgs:
let
developmentPackages = with pkgs; [
nodejs_24
git
curl
jq
ripgrep
fd
python3
];
in
{
default = pkgs.mkShell { packages = developmentPackages; };
}
// pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
# Keep driver and browser revisions paired through the existing lockfile.
# Opt-in so ordinary content editing does not require browser downloads.
browser = pkgs.mkShell {
packages = developmentPackages ++ [ pkgs.playwright-driver ];
PLAYWRIGHT_MODULE = "${pkgs.playwright-driver}/index.mjs";
PLAYWRIGHT_BROWSERS_PATH = pkgs.playwright-driver.selectBrowsers {
withFirefox = true;
withWebkit = false;
withFfmpeg = false;
};
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1";
# Nix supplies browser libraries via patched runtime paths, not apt.
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = "true";
FONTCONFIG_FILE = pkgs.makeFontsConf {
fontDirectories = with pkgs; [
dejavu_fonts
liberation_ttf
noto-fonts
];
};
ASTRO_TELEMETRY_DISABLED = "1";
};
}
);
overlays.default = final: prev: rec {
nodejs = prev.nodejs_22;
yarn = (prev.yarn.override { inherit nodejs; });
};
formatter = forAllSystems (pkgs: pkgs.nixfmt);
devShells = forEachSupportedSystem ({ pkgs }: {
default = pkgs.mkShell {
packages = with pkgs; [
node2nix nodejs nodePackages.pnpm yarn
python3
fd
];
};
});
};
}
-18
View File
@@ -1,19 +1 @@
PUBLIC_AIA_API_BASE=https://api.azinstitute4autism.com
PUBLIC_COUNTERS_MODE=off
PUBLIC_COUNTERS_LIVE_APPROVED=false
PUBLIC_COUNTERS_MOCK_RESULT=success
# Optional override only: absent/empty means live on exactly 16 approved routes.
# PUBLIC_AIA_FORMS_MODE=off
# PUBLIC_AIA_FORMS_MODE=mock
PUBLIC_AIA_FORMS_MOCK_RESULT=success
# Explicit, local-only Form A meeting preview; requires PUBLIC_AIA_FORMS_MODE=mock.
PUBLIC_AIA_FORM_A_PREVIEW=false
PUBLIC_ALLOW_INDEXING=false
# Employee portal ciphertext is a non-PUBLIC build-only input.
# Never supply a passphrase through environment variables or build arguments.
AIA_PORTAL_LOCAL_PREVIEW_APPROVED=false
# AIA_PORTAL_CIPHERTEXT_FILE=/owner-controlled/private/ciphertext.json
# Explicit production-indexing input; it is never placed in Git or source snapshots.
AIA_PORTAL_PRODUCTION_APPROVED=false
# AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE=/absolute/private/employee-portal/approved-production-ciphertext.json
+17 -327
View File
@@ -26,7 +26,7 @@ edits. Stop it with `Ctrl+C`.
Requirements:
- Node.js 22.12 or newer (see `package.json`); the Nix shell supplies Node.js 24
- Node.js 20.19 or newer; the Nix shell currently supplies Node.js 22
- npm
This repository also has a Nix development shell at the repository root:
@@ -38,73 +38,19 @@ cd www
npm install
```
### Local Playwright environment (Linux)
From the repository root, enter the opt-in browser shell:
```sh
nix --extra-experimental-features "nix-command flakes" develop .#browser
cd www
TMPDIR=/tmp npm run build
TMPDIR=/tmp node tools/playwright-smoke.mjs
```
The existing `flake.lock` pairs the Nix Playwright driver and Chromium/headless
shell. `PLAYWRIGHT_MODULE` points directly to that driver; `PLAYWRIGHT_BROWSERS_PATH`
selects its matching browsers. Fontconfig supplies Latin/Arabic fallback fonts.
The ordinary development shell and npm dependencies remain unchanged. This
browser shell is offered on Linux; the existing Darwin development shell is
unchanged. Do not run `npx playwright install` or mix an unrelated npm Playwright
version with these browser revisions.
The smoke test starts Astro preview and Chromium in the **same execution** on an
ephemeral `127.0.0.1` port. It blocks external and non-GET/HEAD requests, loads the
real Spanish privacy and Library pages, verifies staging robots/title/H1, captures
two full-page screenshots in a new `/tmp/aia-playwright-smoke-*` directory, and
closes browser/preview. It does not submit forms or exercise production APIs.
Success establishes browser transport only, not Phase 8 visual or human acceptance.
Use the [Phase 8 guarded browser procedure](reports/phase-8-host-browser-verification-2026-10-14.md)
for full review. Entering the Nix shell does not repair an already-running remote
MCP transport or relax sandbox permissions. If the autonomous environment cannot
access the Nix store, trusted certificates, sockets or browser runtime files, run
the same smoke test from the host terminal. Do not disable TLS verification or
bypass the sandbox. The Nix environment needs host validation before browser
availability can be claimed.
Copy the example environment file when testing the like/view counter or staging
SEO behavior:
Copy the example environment file when testing the like/view counter:
```sh
cp .env.example .env
```
The default values are:
The default value is:
```txt
PUBLIC_AIA_API_BASE=https://api.azinstitute4autism.com
PUBLIC_COUNTERS_MODE=off
PUBLIC_COUNTERS_LIVE_APPROVED=false
PUBLIC_ALLOW_INDEXING=false
```
The site still renders when the AIA API is unavailable. Migration and staging
builds emit `noindex,nofollow` by default. `PUBLIC_ALLOW_INDEXING=true` enables
production publication policy, including per-page noindex exceptions. Exercise
that mode locally with `PUBLIC_ALLOW_INDEXING=true npm run build`; this does
not deploy anything or change environment files. Run `npm run build` afterward
to restore staging output. Only explicitly authorized production deployments
should publish indexing-enabled artifacts.
Ordinary local builds keep counters off. `npm run deploy` deliberately and
non-overridably builds the production artifact with live counters, the approved
API origin and `PUBLIC_COUNTERS_LIVE_APPROVED=true`. Article pages post one
first-party view per real navigation; Library cards only batch-read statistics.
Likes use the existing POST/DELETE API and store only the visitor's chosen slug
set in localStorage. No view cookies or visitor identifiers are created. Run
`npm run test:counters`, then build in live mode and run `npm run
verify:counters -- --browser=chromium` (or `firefox`) for a fully intercepted
browser regression that cannot write production counters.
The site still renders when that API is unavailable.
## View And Build
@@ -127,12 +73,13 @@ Useful development URLs include:
/library
/es
/es/library
/ar
/ar/library
```
### Static Build
### Production Build
Generate the static site with staging indexing protection:
Generate the static production site:
```sh
npm run build
@@ -222,91 +169,6 @@ Article content goes here.
Set `draft: true` while preparing unpublished content.
### Display Headings and Social Metadata
Pages and articles may supply an optional plain-text `displayH1` in frontmatter:
```yaml
title: "The existing SEO title"
displayH1: "The source-supported visible heading"
```
The override changes only the visible H1. It does not change the document or
social title, article cards, navigation labels, or related-post text. Empty,
whitespace-only and non-string overrides fail content validation. Without an
override, articles keep `title`, regular pages keep their existing service/page
heading mappings and title-derived fallback, and homepage/Library components
keep their existing headings. Homepage heading markup stays intact unless a
plain-text override is explicitly supplied. Library template SEO titles remain
unchanged. Front Matter CMS exposes the optional field for pages and blog posts.
Existing featured images and page banner fallbacks supply `og:image` and
`twitter:image`. Relative paths resolve against the public origin in
`src/data/site.json`, never a preview host or an external canonical. Existing
`alt` text supplies both image-alt metadata tags only when it describes the
selected featured image; no descriptions are invented for banner fallbacks.
Pages without a selected image omit image tags and retain the `summary` card;
image pages retain `summary_large_image`.
`og:locale` is omitted: the content languages `en`, `es` and `ar` do not establish
the regional `language_TERRITORY` values required by the
[Open Graph protocol](https://ogp.me/). Regional targeting remains a human
localization decision. HTML language/direction and hreflang are unchanged.
Run `npm run test:seo` for isolated real-Astro builds covering heading defaults,
overrides, schema rejection, image metadata and shared publication invariants
in staging and indexing modes. Fixtures never modify the working content or
the project's `dist/`. See the dated Phase 4A section of
[`reports/migration-summary.md`](reports/migration-summary.md) for source evidence.
### Publication, Canonicals, and Sitemap
`src/utils/publication-policy.ts` owns route eligibility, normalized public
URLs, canonical validation, robots values, and sitemap eligibility.
`src/utils/publication.ts` loads the Astro collections into that manifest.
`src/pages/[...slug].astro` generates every content route from eligible entries,
including home and Library indexes; their existing presentation components are
under `src/components/pages/`. Shared SEO and the generated sitemap use that
same manifest. The route and source-link audits also reuse the policy.
- `draft: true` means unpublished: no generated HTML route in either build mode.
The Arabic homepage `/ar` remains a draft; published Arabic Library routes
remain available. Navigation does not link to the unpublished homepage.
- `noindex: true` keeps a published route accessible, emits `noindex,follow`
in indexing-enabled builds, and excludes it from the sitemap. It defaults
to `false`. Staging always overrides this with `noindex,nofollow`.
- An omitted `canonical` gets the normalized public URL from `site.json` and
its local route. A supplied local canonical must match that route. Invalid
canonicals, duplicate canonical targets, and route collisions fail validation.
- Verified syndicated articles use their existing `canonical` field for the
external publisher URL. External-canonical routes are excluded from the
sitemap even when they are not marked noindex. Do not use canonical values
to create local routes or sitemap locations.
- `src/pages/sitemap.xml.ts` generates `dist/sitemap.xml` on every build.
Staging emits an empty sitemap and does not advertise it in `robots.txt`.
Indexing-enabled builds include only eligible, indexable, self-canonical
local routes. There is no hand-maintained `public/sitemap.xml`.
- `npm run generate:sitemap` is a compatibility command that runs the Astro
build; it no longer writes a separate public sitemap from frontmatter strings.
The verified noindex exceptions are `/schedule-consultation`, `/employee-portal`,
`/library/community-highlight-meet-rula-diab`, and
`/library/new-aia-scottsdale-office`. The last two also retain their verified
external canonicals. The dated evidence is in `reports/migration-summary.md`.
Run `npm run test:publication` for policy tests and isolated builds of the
actual application in staging and indexing-enabled modes. Fixtures test draft
content, draft home/Library indexes, missing and external canonicals, and
generated head/sitemap consistency without modifying the working site's output.
The policy is TypeScript; Node audit/test commands use `--experimental-strip-types`
for compatibility with the declared Node 22.12 minimum. Dependencies are unchanged.
After publication changes, build and run `npm run audit:routes -- --offline`
before `npm run audit:routes -- --check`. This creates a newly dated local
reconciliation using saved production observations, preserving earlier evidence.
Saved rendered metadata is specific to its build mode: after restoring the
normal staging build, reconcile that output again before checking it.
### Links And Buttons
Use normal Markdown links for links within prose:
@@ -334,46 +196,6 @@ Available sizes are `default` and `small`. A `_blank` target automatically adds
Normal Markdown links remain preferred for ordinary page and article content.
### Stable Heading Links
Astro automatically generates an ID for each Markdown heading. In `.md` files,
when a section needs a stable, editorially controlled fragment link, add an
explicit ID with Sätteri heading-attribute syntax:
```md
## Accepted Insurance Carriers {#accepted-insurance-heading}
```
Link to it with the resulting fragment URL:
```md
[View accepted carriers](/insurance#accepted-insurance-heading)
```
Keep explicit IDs unique within the page, lowercase, and hyphenated. Treat a
published ID as permanent so inbound links do not break when heading text is
edited. The installed MDX parser rejects this shorthand, independently of
directive parsing. In `.mdx` files, use an explicit HTML heading instead:
```mdx
<h2 id="accepted-insurance-heading">Accepted Insurance Carriers</h2>
```
### Markdown Directives
Sätteri directive parsing is disabled. The content corpus has no intentional
container (`:::name`), leaf (`::name`), or text (`:name`) directives, and no
directive transformation plugins are registered. Enabling parsing silently
removed literal text such as `:1` in `1:1`, `:00` in times, and `:Plan` after
an adjacent colon. Heading attributes remain enabled.
Run `npm run test:markdown` after changing the Markdown/MDX configuration. It
builds temporary fixtures and the affected content through the actual Astro
configuration, checking ratios, punctuation, times, URLs, code, and explicit
heading IDs. It makes no production requests and leaves no fixture routes in
the site. Any future directive feature needs compatible rendering and must
preserve these literal-content checks.
### Front Matter CMS
The project includes `frontmatter.json` for the Front Matter CMS VS Code
@@ -400,30 +222,14 @@ benefits
skills
insurance
esa
hsaFsa (optional; English only where published)
financialHelp
process
director
testimonials
logos (optional)
```
Keep homepage copy in those named blocks so the page remains easy to scan in
Front Matter CMS and VS Code. `src/content.config.ts` validates the structure.
`hsaFsa` uses `heading`, `body`, `image`, and `imageAlt`; omit the whole block
where no section is published. It renders between ESA and financial help.
`logos.items` holds `file`/`alt` pairs after testimonials. Process steps accept
an optional `href`; use an existing intake route and section ID in the same
language. Steps without a destination remain plain content.
### Edit The Team Page
The English Team page uses the validated `team:` frontmatter block in
`src/content/pages/en/team.md`. That block is the single source for the intro,
ordered clinical groups, ABA care team, member names/roles/images, and careers
content. The Markdown body contains no second roster. Update the structured
frontmatter rather than hardcoding people in `TeamPage.astro`; image filenames
refer to `public/assets/images`.
### Images And Downloads
@@ -479,10 +285,7 @@ src/data
### Add A Translation
Use the same nonempty `translationKey` across genuine translated entries in
the **same collection**. The key is an explicit equivalence declaration, not a
URL or an entry reference. Slugs may differ; similar slugs alone never create a
relationship. Do not change keys to manufacture translation pairs.
Use the same `translationKey` across translated entries:
```txt
src/content/blog/en/post-slug.md
@@ -500,32 +303,7 @@ The URLs become:
Arabic routes automatically render with `lang="ar"` and `dir="rtl"`.
The shared publication manifest supplies both the language switcher and SEO
alternates. A translation set needs at least two eligible members. Drafts,
unpublished placeholders, noindex pages, and external-canonical pages do not
participate. Mark placeholders `draft: true`; `/ar` remains unpublished.
Author records have no generated routes yet and cannot participate.
One member per language per collection/key is allowed, including draft members;
duplicates and blank/whitespace-padded keys fail validation. A lone key is valid
and emits no alternate: it does not assert that a particular missing language
exists. Dangling graph references, wrong-family targets, ineligible targets,
and nonreciprocal links fail validation. The rendered-output regression checks
also fail if an alternate target has no generated HTML file.
Indexing-enabled builds emit the same absolute hreflang links on every member,
including its own language. `x-default` points to the eligible English member
only; sets without one omit it. Staging suppresses hreflang while retaining the
eligible language menu and global `noindex,nofollow`. Unpaired/excluded pages
retain their current-language label without an empty interactive menu.
Run `npm run test:publication`, `npm run build`, and
`PUBLIC_ALLOW_INDEXING=true npm run build` to validate both modes. Finish with
`npm run build` to restore staging. See `reports/migration-summary.md` for
Phase 3B's exact route sets, evidence, and route-audit refresh commands.
Do not publish unreviewed machine translations. Do not invent translations;
substantive translation changes require human language review.
Do not publish unreviewed machine translations. Clearly mark placeholders.
### Edit A Blog FAQ
@@ -536,49 +314,12 @@ import FAQAccordion from '../../../components/FAQAccordion.astro';
```
Edit the component's `label`, `heading`, and `items` data in the post. Keep
`answer` and `answerHtml` consistent. JSON-LD derives its answer text from the
actual visible `answerHtml` when supplied, otherwise from the rendered `answer`
fallback. Shared FAQ markup, styling, interaction, and schema generation remain
in `src/components/FAQAccordion.astro`, using `src/utils/structured-data.ts`.
The standalone FAQ page passes its rendered Markdown/MDX slot as `sourceHtml`
to the same component. Its server schema describes the direct H3 questions and
following answer nodes that the existing browser code turns into accordions.
Runtime-only sources without server content emit no invented FAQ schema. Do
not mix `items` with `sourceSelector`. Duplicate questions, multiple schema
producing accordions on one page, empty answers and conflicting canonical
props fail validation; consolidate questions into one accordion per page.
### Article and FAQ Structured Data
Article JSON-LD uses the existing SEO `title`, description, featured image,
language, `date`, optional `updatedDate`, and the exact locale/slug match in the
authors collection. Dates use calendar-day precision; article/card bylines
format that day in UTC to avoid shifting it on the build host. Missing
modification dates are omitted. Missing or ambiguous author references fail validation.
No author archive URL or publisher is invented. `displayH1` does not change
the schema headline. No new frontmatter fields are required.
BlogPosting and FAQPage emission reuse the manifest's `sitemapEligible` record
gate: drafts, noindex records and external-canonical records are excluded.
This gate is independent of the build's global indexing switch, so staging
can exercise schema while retaining its global noindex, empty sitemap and
absent hreflang. The existing site organization block remains unchanged.
These schemas describe the rendered local records; they do not certify that
older article dates or FAQ answers have been reconciled with production.
Phase 6C drift observations and validation results are recorded in
`reports/migration-summary.md`. Run `npm run test:seo` and
`npm run test:publication`, and validate both build modes before publication.
`answer` as plain text for JSON-LD and `answerHtml` as the matching visible
answer. Shared FAQ markup, styling, interaction, and schema generation live in
`src/components/FAQAccordion.astro`.
## Reports And Utilities
For the current migration checkpoint, next Codex phase, ratified decisions,
and outstanding cutover blockers, begin with the
**[living session handoff](reports/SESSION_HANDOFF.md)**. Update that short
handoff at each accepted milestone transition; detailed historical evidence
remains in `reports/migration-summary.md`.
Migration reports are stored in `reports/`.
Useful commands:
@@ -592,65 +333,14 @@ npm run audit:links
The live crawl is optional and may fail in restricted network environments.
## Referral CTA
The public `/referrals` page preserves the existing site's **Refer a Client**
button, linking directly to https://form.jotform.com/231638510219149. The
site does **not** embed a referral form or require Form C. This destination is
separate from Form A's 16 allowlisted placements. Legacy-hosted-form privacy,
recipient, accessibility and operational acceptance remain the owner's release
responsibility.
## Forms
As of the owner decision on 2026-10-30, `npm run dev` and `npm run build`
use live Jotform Form A on exactly 16 approved placements: 10 immediate frames
and six deferred bilingual service drawers. No Form A flags are required.
Public development-host forms are owner-authorized. This does not authorize cutover.
Forms are intentionally static and do not submit anywhere. Before production:
Use `PUBLIC_AIA_FORMS_MODE=off npm run build` for an offline artifact, or
`PUBLIC_AIA_FORMS_MODE=mock npm run dev` for synthetic fixtures. Missing/empty
mode means live; obsolete `isolated-test` and other invalid values produce an
explicit configuration error. Remove old approval/environment variables from
local settings. Indexing and form mode remain independent of counter mode.
See the [current Form A guide](integrations/jotform/README.md) for the exact
registry, safeguards, rollback and owner acceptance requirements. Form C remains
inactive. Employee-portal private input retains its own separate gates.
Verify matching output with
`node tools/phase10-artifact-verify.mjs --mode=staging --forms=live --counters=off`;
use `--mode=indexing` for indexing output and `--forms=off` or `--forms=mock`
for those explicit builds. Production counter artifacts require
`--counters=live`. No actual submissions or production counter writes run in
automated tests.
## Static releases and employee portal
The Contabo deployment interface is intentionally separate from NixOS changes.
Use [the release runbook](integrations/nixos/deploy.md) for `npm run deploy`,
dry-run, rollback, the encrypted production portal input and the separate
one-time employee-resource installer. The server-side installer is a root-only
POSIX shell script using NixOS base tools; it does not require Node.js on
Contabo. Ordinary releases never copy employee documents into `dist`;
protected staff and management resources remain under server-controlled Basic
Auth namespaces. After a successful unlock, the page keeps that role's code
only in memory and uses it for same-origin authenticated document fetches. The
response is downloaded as a local Blob, so employees do not receive a second
browser authentication prompt. Cross-role requests are stopped before
credentials are sent; direct resource URLs still require nginx authentication.
Codes are never put in URLs or browser storage. The accepted interim portal is
explicitly non-PHI.
### Google Ads consultation-form conversion handoff
The Google Ads conversion ID, label, and privacy-gated Astro integration
instructions are in
[`reports/google-ads-consultation-conversion.md`](reports/google-ads-consultation-conversion.md).
This is documentation only: **do not install Google tags or conversion snippets**
on health-service pages or turn on enhanced conversions until AIA's
privacy/HIPAA and advertising-policy review explicitly approves the complete
data flow. Any future measurement needs separately approved success and privacy semantics; the former API-success premise is historical and no tracking is active.
1. Select a form backend.
2. Connect the forms.
3. Add spam protection.
4. Test validation, confirmation, and failure states.
## Troubleshooting
+1 -11
View File
@@ -1,21 +1,11 @@
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import { satteri } from '@astrojs/markdown-satteri';
import site from './src/data/site.json' with { type: 'json' };
export default defineConfig({
site: site.url,
site: 'https://www.azinstitute4autism.com',
trailingSlash: 'never',
compressHTML: true,
integrations: [mdx()],
markdown: {
processor: satteri({
features: {
headingAttributes: true,
// No directive consumers: parsing them drops literal ratios and times.
directive: false
}
}),
shikiConfig: { theme: 'github-light' }
}
});
-3
View File
@@ -13,7 +13,6 @@
"pageBundle": false,
"fields": [
{ "title": "Title", "name": "title", "type": "string", "required": true },
{ "title": "Display H1", "name": "displayH1", "type": "string" },
{ "title": "Description", "name": "description", "type": "string" },
{ "title": "Slug", "name": "slug", "type": "string", "required": true },
{ "title": "Language", "name": "lang", "type": "choice", "choices": ["en", "ar", "es"] },
@@ -29,7 +28,6 @@
"pageBundle": false,
"fields": [
{ "title": "Title", "name": "title", "type": "string", "required": true },
{ "title": "Display H1", "name": "displayH1", "type": "string" },
{ "title": "Description", "name": "description", "type": "string" },
{ "title": "Slug", "name": "slug", "type": "string", "required": true },
{ "title": "Date", "name": "date", "type": "datetime", "required": true },
@@ -49,7 +47,6 @@
"pageBundle": false,
"fields": [
{ "title": "Name", "name": "name", "type": "string", "required": true },
{ "title": "Display name (published heading/byline)", "name": "displayName", "type": "string" },
{ "title": "Slug", "name": "slug", "type": "string", "required": true },
{ "title": "Description", "name": "description", "type": "string" },
{ "title": "Avatar", "name": "avatar", "type": "image" },
-185
View File
@@ -1,185 +0,0 @@
# Employee portal compatibility and private migration
Recorded 2026-11-04. The clinical director accepted the collected, non-PHI
staff and management portal content and the interim shared-code presentation.
Browser-side decryption remains access friction rather than individual
authentication, revocation, a secure session, or a HIPAA determination.
The same successfully validated code authorizes protected document downloads
for that role during the current page session. The browser keeps it only in a
closure, performs a same-origin authenticated fetch, and saves the returned
document without opening nginx's native Basic Auth dialog. Staff uses the
`staff` username and stream `b`; management uses the `management` username and
stream `a`. Direct URLs remain nginx-protected, cross-role fetches are rejected
before credentials are sent, and failed authenticated downloads show an inline
error without direct-navigation fallback. No code enters a URL, browser
storage, public artifact, or log. Downloads use a bounded safe form of the
approved link label and preserve the validated extension from the protected
SHA-256 server destination; server resources are not renamed.
## Approved production ciphertext
An indexing-enabled production build may include one owner-approved encrypted
two-stream payload when both of these non-public build inputs are set:
```sh
AIA_PORTAL_PRODUCTION_APPROVED=true
AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE=/absolute/private/employee-portal/approved-production-ciphertext.json
```
The build rejects missing, malformed, symlinked, oversized, wrong-mode, or
simultaneous local-preview/production inputs. It never decrypts the payload at
build time. `/employee-portal` remains noindex, sitemap-excluded and
hreflang-excluded. See [the deployment runbook](../nixos/deploy.md) for the
approved release and protected-resource installation commands.
## Source and private collection
The 42 approved non-PHI resources have already been collected under the ignored
`private/employee-portal/hubfs/` workspace. Collection and clinical review are
complete. Do not run a new collection pass for production preparation.
Production preparation is an owner-only, hidden-prompt sequence. The first
command identifies the encrypted streams from the staff and management codes;
the codes are never accepted in arguments, environment variables, files or
output:
```sh
npm run portal:prepare -- identify \
/home/alice/projects/wrk/aia/local-archives/aia-employee-portal-hubspot-footer-source.txt
npm run portal:prepare -- propose-mappings \
/home/alice/projects/wrk/aia/local-archives/aia-employee-portal-hubspot-footer-source.txt
```
Review the private mapping summary. The role rule maps staff-only references to
`/staff-resources/`, management-only references to `/management-resources/`, and
duplicates a shared source into both protected namespaces. After the owner
approves that operational policy, run:
```sh
npm run portal:prepare -- approve-mappings \
/home/alice/projects/wrk/aia/local-archives/aia-employee-portal-hubspot-footer-source.txt
npm run portal:prepare -- rewrite-production \
/home/alice/projects/wrk/aia/local-archives/aia-employee-portal-hubspot-footer-source.txt
```
The rewrite command prompts for both codes again, rewrites every approved legacy
resource URL, re-encrypts with fresh salts and IVs, verifies each role privately,
and atomically installs `approved-production-ciphertext.json` plus a matching
private `production-readiness.json`. It refuses unresolved `/hubfs/` references.
Prior manifests and production ciphertext are retained as timestamped private
backups.
### Mapping approval versus server verification
`mappingApproved`, `accessPolicyApproved`, and `rewriteApproved` mean the
verified collected source has an approved role and safe protected destination
and may be prepared or installed. They do not claim the destination exists.
`destinationInstalled`, `destinationHashVerified`,
`destinationPermissionsVerified`, and `destinationAccessVerified` remain false
until an authorized VPS rehearsal actually installs the file and verifies its
bytes, `root:nginx` permissions, Basic Auth boundary and protected URL. Local
preparation and installation accept the first state; release acceptance must
still complete the second state before browser cutover.
Read-only legacy footer source:
`/home/alice/projects/wrk/aia/local-archives/aia-employee-portal-hubspot-footer-source.txt`.
The original stays outside Git as rollback evidence. The 42-file collection and
its accepted content are complete; no current command downloads resources.
Private output is `private/employee-portal/`: directories 0700, manifests and
binary resources 0600. This exact subtree is gitignored and outside Astro's
public directory. Filenames are SHA-256 hashes of source URLs, independently
verified by content hashes. The manifest retains original references, labels,
view membership, MIME, bytes, status and delivery/classification decisions.
The manifest preserves the original source URL, collection hash, size, reference
membership and accepted source evidence. Public legacy reachability did not
infer public approval.
Before every artifact transfer, verify that only `dist` is copied and that it
contains no private manifest, document or real ciphertext unless that ciphertext
has separately been authorized for the local preview. Never archive the whole
working directory as a deployable artifact.
## Historical collection and rewriting recovery notes
The original source, collection manifests, collected bytes and prior ciphertext
revisions remain recovery evidence. Do not change their classifications or
destination flags by hand; use the production-preparation sequence above so
stream identity, references, source hashes and protected destinations remain
consistent. CSS/srcset dependencies remain an explicit error rather than a
silent rewrite.
## Local preview and content safety
Use a retained private ciphertext revision:
```sh
AIA_PORTAL_LOCAL_PREVIEW_APPROVED=true \
AIA_PORTAL_CIPHERTEXT_FILE=/absolute/private/ciphertext-TIMESTAMP.json \
PUBLIC_AIA_FORMS_MODE=off PUBLIC_ALLOW_INDEXING=false \
npm run dev -- --host 127.0.0.1
```
The 2026-10-30 revision removes dependence on the retired Form A environment role. Form mode is independent; `off` above is optional for local testing and cannot grant portal approval. The page defaults to locked/unavailable without its own explicit approval and valid private input. Indexing
builds cannot include it. The codes never go to a server, storage or URL. No
native form submits; Enter and Unlock use local WebCrypto. Only the matching
stream is displayed; refresh or leaving the page locks it again.
The passive DOM renderer preserves headings, lists, text, tables and safe
HTTPS/mailto/tel links, with no referrer on links. It rejects scripts, inline
handlers, styles, media, embedded forms and unknown tags. Real portal markup
has not been decrypted or reviewed; any removed behavior must be reviewed with
the owner before claiming fidelity. It must not silently become arbitrary
script execution. No real encrypted stream or plaintext is in Git.
### Scoped presentation correction, 2026-10-30
The renderer now maps only `hs-button`, `content-button`, or
`portal-resource-button` anchor tokens, or exact inline AIA orange background
colors (`#ffbd59` / `#ff914d`), to the local `portal-resource-button` class.
It does not copy the original style or arbitrary classes. These are narrow
compatibility candidates, not a claim that encrypted real views have been
inspected. HTTPS/mailto/tel links retain the existing safe URL checks; contact
links receive a local dark-orange accent for readable contrast. Table scope
and bounded numeric row/column spans are preserved. All other executable or
unapproved attributes remain removed.
The follow-up styling correction recognizes the live portal's `Daily Lineup
Report` and `Monthly Lineup Report` link labels, even when their original
HubSpot classes or inline fills are absent. It maps only those links to the
existing orange resource-button style; arbitrary anchors remain ordinary links.
Both unlocked views now use the site's orange accent for list-item markers.
The source classes and styles still do not reach the passive DOM.
### Staff resources and Management Templates, 2026-11-01
The owner observed that the non-management (general-staff) portal still lost
HubSpot's resource-button presentation. After **sanitizing** the decrypted DOM,
a headed `Management Templates` section identifies the general-staff resource
view. Valid HTTP(S) resource links in that view receive only the local
`portal-resource-button` class; `mailto:` and `tel:` retain contact-link
styling. Neither destination validation nor removed legacy classes/styles,
scripts, media or HTML attributes are relaxed.
The `Management Templates` unordered list receives a local
`portal-template-grid` class: two columns at desktop widths (768px+),
one column on smaller screens. Semantic list order and keyboard tab order
are retained, with responsive full-width buttons. This is a presentation
change only: it does not infer or approve employee resource access.
Synthetic staff/management browser fixtures check the distinction and
responsive columns. The actual decrypted staff source remains private;
owner should confirm layout and links in the local preview before merging.
Scoped typography, spacing, lists, table rules and keyboard focus apply to both
unlocked streams. Synthetic staff/management fixtures exercise these mappings
at 320/390/768/1440px. Owner must inspect the real views privately to confirm
legacy button recognition and source fidelity; if a different class is used,
provide sanitized class semantics rather than decrypted content or credentials.
Before owner acceptance: validate two real view codes privately, inspect every
resource/category, responsive directories, focus, link semantics and sanitization
impact. Check wrong-code feedback, keyboard unlock, no-JS explanation and refresh.
Production must use a separately reviewed runtime ciphertext delivery mechanism;
this batch intentionally provides only a gated local build input. Browser-delivered
ciphertext is publicly downloadable by anyone able to reach that preview.
-156
View File
@@ -1,156 +0,0 @@
# AIA Form A Jotform styling and conditional-button guide
This directory contains the accepted CSS backup and integration guidance for AIA Form A. [`aia-form-a.css`](./aia-form-a.css) is intended for Jotform Classic Forms' **Form Designer → Styles → Inject Custom CSS** under owner-controlled configuration review. The existing repository CSS is the accepted backup; do not regenerate it from Astro styles.
The CSS translates the existing AIA form treatment: Rubik typography, blue labels and text, `#fcf9f5` inputs with `#edeef3` borders, the `#ffbd59` filled button, the `#ff914d` hover/focus border, four-pixel corners, visible validation errors, and strong keyboard focus. The Astro page supplies the heading, introduction, privacy-policy link, and surrounding card. The stylesheet therefore removes the Jotform surface rather than adding another header, footer, or nested card.
The selectors target Jotform Classic Forms identifiers such as `#form`, `.form-all`, `.form-line`, `.form-label`, `.form-sub-label`, `.form-required`, `.form-textbox`, `.form-dropdown`, `.form-textarea`, `.form-error-message`, and `.form-submit-button`. Jotform's final generated DOM must be checked in the account before relying on pixel-level parity. The stylesheet does not hide required indicators, error messages, honeypots, or focus outlines, and it does not request fonts or other external assets.
The current Builder theme reconciliation adds narrowly scoped `!important` declarations to the outer surface, labels, inputs, and submit-button treatments that Jotform's generated theme otherwise overrides. Error, required-indicator, and focus rules remain visible and are deliberately not reset. The account owner must still confirm the final generated DOM and rendered form after any Jotform theme or field change.
## Installation and comparison
1. Open the approved Form A in AIA's HIPAA-enabled Jotform account. Do not change its fields or settings from this repository workflow.
2. Preserve the approved account configuration; account changes and site cutover require their separate authorization.
3. Paste the contents of `aia-form-a.css` into Jotform's custom CSS area.
4. Compare the Jotform preview with the Astro Form A mock at 390px and 1440px. Check the form surface, label rhythm, input height, button fill, outlined hover/focus state, error state, and mobile reflow.
5. Check both English and Spanish configurations. Confirm translated labels, required indicators, validation messages, confirmation copy, and the accessible iframe title supplied by the parent Astro integration.
6. Test the form in a real embedded iframe and on the direct hosted-form fallback. Confirm the iframe has a practical mobile height, does not create horizontal overflow, and does not trap keyboard focus.
The optional Astro meeting preview requires `PUBLIC_AIA_FORMS_MODE=mock` and `PUBLIC_AIA_FORM_A_PREVIEW=true` in a non-indexing build. It does not load Jotform and is not a live submission test.
## Current Form A operation — superseding decision, 2026-10-30
The owner authorizes real Form A on the publicly reachable development host
`https://aia.web3app.dev/`. Normal development and static builds use **live** Form A
without environment flags. This intentionally supersedes the former isolated-test
and seven-route production approval gates. It is not site-cutover authorization.
From `www/`:
```sh
npm run dev
npm run build
# Optional offline/restricted artifact:
PUBLIC_AIA_FORMS_MODE=off npm run build
# Optional synthetic fixtures:
PUBLIC_AIA_FORMS_MODE=mock npm run dev
```
`PUBLIC_AIA_FORMS_MODE` is optional; missing/empty means `live`. The only accepted
values are `live`, `off`, and `mock`. Remove obsolete `isolated-test` settings from
local environment files; invalid explicit values stop the build with actionable
guidance. The former live/isolated/consultation/production approvals and form
environment role are removed, with no replacement gates. `PUBLIC_ALLOW_INDEXING`
controls publication independently: both staging and indexing builds use the same
16 placements. Explicit off/mock builds contain no real Form A iframe.
One typed registry in `src/utils/form-integration.ts` fixes every route, locale
and context. No visitor query, referrer, arbitrary URL or option preselection is
forwarded. The only origin/ID is `https://form.jotform.com/262946078314059`.
Every URL has exactly `formContext` and `language` parameters:
| Context | Routes | Loading |
|---|---|---|
| contact | `/contact` (en), `/es/contact` (es) | Immediate, 2 |
| landing | `/lp/aba-therapy`, `/lp/aba-insurance`, `/lp/aba-ahcccs`, `/lp/aba-private-pay`, `/lp/early-intervention` (en) | Immediate, 5 |
| consultation | `/client-consultation` (en), `/es/client-consultation` (es), `/schedule-consultation` (en) | Immediate, 3 |
| consultation | `/aba-therapy`, `/autism-evaluations`, `/learner-social-club` (en), and their `/es/` counterparts (es) | Deferred, 6 |
The context is presentation-only. Physical Form B is retired. No Form C is planned.
`/referrals` independently links to the existing hosted Jotform
`https://form.jotform.com/231638510219149`, not to Form A. That link is
owner-directed but its legacy form's runtime privacy/recipient acceptance remains
separate from Form A. Other routes cannot acquire Form A by setting a mode.
The typed future Academy service copy does not publish another page.
Live service drawers open at four seconds OR 50% scroll, canceling the unused
trigger. Dismissal or verified completion sets the existing shared 30-day
suppression timestamp. The existing service CTA overrides automatic suppression;
without JavaScript it remains a normal consultation-page link. Jotform loads only
when the drawer opens. Off mode never automatically opens an inactive drawer.
Mock mode retains the existing synthetic fixture workflow.
A verified `submission-completed` message must match the exact approved origin,
actual activated/open iframe window, approved form ID and action. It displays a
localized acknowledgment, waits five seconds, then uses the existing slide-out.
Duplicate messages cannot restart the countdown. Manual close/navigation cancels
it; suppression remains. Deliberate reopening after completion creates a fresh
iframe. Provider-envelope acceptance still requires the owner-controlled real
submission check; synthetic browser messages are not that acceptance.
The shared iframe preserves fixed responsive heights, accessible EN/ES titles,
`referrerpolicy="no-referrer"`, and
`sandbox="allow-forms allow-scripts allow-same-origin"`. No popup, top-navigation,
camera, microphone, payment or geolocation permissions are added. The hosted
fallback is outside the iframe and hidden without layout space until a 15-second
missing-load timeout. Late load hides it; disposal cancels timers. A localized
`noscript` fallback remains. Load does not prove application health or submission.
No helper script, cross-origin DOM inspection, arbitrary messaging or submission
forwarding is introduced. The official resize handler remains unimplemented and
conditionally acceptable only after its separate security/browser review.
Owner-reported direct EN/ES synthetic acceptance and sampled embedded acceptance
(English contact, Spanish contact and one ABA landing page) remain recorded as
owner evidence. This change does not independently verify Jotform or resolve its
Spanish consultation dropdown discrepancy, runtime telemetry, fluent-language,
screen-reader, final HTTPS-host or operational recipient review.
For form rollback, explicitly set `PUBLIC_AIA_FORMS_MODE=off`, rebuild, verify
`--forms=off`, and use the separately authorized artifact-switch procedure.
Removing that override restores live, so removing settings is **not** rollback.
Do not change the Jotform account as part of an Astro rollback.
Artifact checks (build matching output first):
```sh
node tools/phase10-artifact-verify.mjs --mode=staging --forms=live
# For PUBLIC_ALLOW_INDEXING=true output:
node tools/phase10-artifact-verify.mjs --mode=indexing --forms=live
# For explicit off or mock output, select the matching --forms value.
```
Employee-portal ciphertext remains separately gated by its own approval, private
input and non-indexing preview requirement. Form A modes cannot authorize it.
## Existing professional referral destination (owner decision 2026-11-01)
`/referrals` has one `Refer a Client` link to
[the existing hosted Jotform](https://form.jotform.com/231638510219149). It does not embed Form A
or use Form C. No new form, question, Jotform integration, query parameter or
notification routing is introduced. Test the link and verify the separate
existing form's privacy, field necessity, recipients and confirmation with its
account owner before release.
## Form context and button labels
The current Form A design uses a hidden `formContext` value with fixed, approved values such as `contact` and `landing`. Jotform does not provide a native conditional rule that changes one Submit button's accessible label safely in every context. If owner-approved context-specific labels are required, use multiple native Jotform Submit buttons and Jotform's conditional visibility rules:
- Add one native Submit button for each approved context/language label.
- Show exactly one intended Submit button for the current, validated `formContext`.
- Keep every button a real Jotform Submit control; do not use CSS `::before`/`::after` text as a label.
- Verify that every visible variant submits through the same approved form and preserves the honeypot and validation behavior.
- Make the no-context and invalid-context states fail closed: no ambiguous extra button and no unintended submission path.
- Verify keyboard order, focus visibility, screen-reader names, English/Spanish labels, and mobile layout for every variant.
All five landing routes use Form A's fixed `landing` context. The nine consultation
placements use its fixed `consultation` context. Jotform owns native Submit labels
and conditions. Do not add an external Astro button that attempts to submit a
cross-origin iframe.
## Verification checklist
- [x] Direct English/Spanish Form A language handling, conditional email requirement, synthetic submission and native thank-you were owner-verified; this is not embedded-iframe acceptance.
- [x] Direct staff-notification/autoresponder delivery, generic no-answer/no-PDF content, fixed Reply-To, recipient access/retention, and absent webhooks/integrations were owner-verified for Form A.
- [ ] Exact remaining Form A consultation question properties, choices, conditional routing and availability, and consultation language/configuration, are approved.
- [ ] English and Spanish embedded-iframe labels, validation, confirmation, and button variants are reviewed by fluent-language owners.
- [ ] The hidden honeypot remains present, effective, and excluded from user-facing visual changes.
- [ ] Exactly one native Submit button is visible for every valid context.
- [ ] Invalid or missing context does not expose an unintended submission path.
- [ ] No PHI-bearing answer, PDF, recipient, redirect, webhook, or HTTP POST forwarding is inherited without privacy/security approval.
- [x] Owner-reported embedded synthetic submission and confirmation passed on English contact, Spanish contact and one ABA landing placement; record the exact ABA path in the owner test log before release.
- [ ] All sixteen placements have final responsive, keyboard, screen-reader and fluent-language acceptance, including timeout/fallback and error expansion.
- [ ] Jotform runtime requests, telemetry and cross-origin failure behavior are reviewed with privacy/security owners.
- [ ] No Jotform, Contabo, analytics, advertising, or production API request is made by off/mock builds.
Existing owner-verification scopes remain recorded in the contract/checklist. Outstanding consultation configuration acceptance, runtime/privacy, accessibility, fluent-language and site-release gates remain open. Default-live Form A is owner-authorized; this guide does not authorize Jotform account changes or site deployment.
-252
View File
@@ -1,252 +0,0 @@
/* ==========================================================
AIA FORM A — JOTFORM CUSTOM CSS
Form ID: 262946078314059
Maximum form width: 640px
========================================================== */
/* Document and language selector */
html.supernova,
html.supernova body,
body.supernova {
background: #fff !important;
background-image: none !important;
}
/* Avoid horizontal overflow, including on the thank-you page */
body {
margin: 0 !important;
}
/* Confirmation page styling */
body.thankyou,
body.thankyou #stage {
background: #fff !important;
background-image: none !important;
}
.jfLangDd.jfLangDd--match-form {
padding: 12px 0 !important;
}
/* Form container */
form[id="262946078314059"] {
width: 100% !important;
max-width: 640px !important;
margin: 8px auto !important;
box-sizing: border-box;
}
.form-all {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
background: #fff !important;
border: 0 !important;
box-shadow: none !important;
color: #254080;
font-family: Rubik, Arial, sans-serif;
}
.form-all .form-section {
margin: 0 !important;
padding: 0 !important;
}
/* Field layout */
.form-all .form-line {
margin: 0 !important;
padding: 0 0 21px !important;
background: transparent !important;
border: 0 !important;
}
.form-all .form-input-wide {
margin-top: 0 !important;
padding-top: 0 !important;
}
/* Labels and sublabels */
.form-all .form-label,
.form-all .form-label-left,
.form-all .form-label-right,
.form-all .form-label-top {
color: #254080 !important;
font-size: .875rem;
font-weight: 700;
line-height: 1.35 !important;
margin: 0 0 6px !important;
padding: 0 !important;
}
.form-all .form-sub-label {
color: #254080;
font-size: .75rem;
line-height: 1.3 !important;
margin: 4px 0 0 !important;
padding: 0 !important;
}
.form-all .form-sub-label-container {
margin-top: 0 !important;
margin-bottom: 0 !important;
}
.form-all .form-required {
color: #a21c28 !important;
margin-left: .2rem;
visibility: visible;
}
/* Inputs */
.form-all input.form-textbox,
.form-all select.form-dropdown,
.form-all textarea.form-textarea {
background: #fcf9f5 !important;
background-image: none !important;
border: 1px solid #edeef3 !important;
border-radius: 4px !important;
box-shadow: none !important;
box-sizing: border-box;
color: #254080 !important;
font-family: inherit;
font-size: 1rem;
line-height: 1.4;
min-height: 2.75rem;
padding: .55rem .7rem;
max-width: 100%;
}
/* Preserve two-column name fields */
.form-all .form-sub-label-container input.form-textbox {
width: 100% !important;
max-width: 100% !important;
}
/* Full-width phone and email fields */
.form-all
.form-line:is(
[data-type="control_phone"],
[data-type="control_email"]
)
:is(.form-input, .form-input-wide, input.form-textbox) {
width: 100% !important;
max-width: 100% !important;
}
/* Message field */
.form-all textarea.form-textarea {
width: 100% !important;
min-height: 5.5rem !important;
resize: vertical;
}
/* Radio buttons and checkboxes */
.form-all .form-radio-item,
.form-all .form-checkbox-item {
color: #254080;
line-height: 1.4;
margin: 0 .75rem .2rem 0 !important;
padding: 0;
}
.form-all .form-radio,
.form-all .form-checkbox {
accent-color: #254080;
}
/* Submit button and wrapper */
.form-all .jf-form-buttons,
.form-all .form-buttons-wrapper {
box-sizing: border-box;
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
background: transparent !important;
border: 0 !important;
}
.form-all .form-submit-button,
.form-all button[type="submit"] {
width: 100%;
box-sizing: border-box;
min-height: 3rem;
padding: .65rem 1.2rem;
background: #ffbd59 !important;
background-image: none !important;
border: 2px solid #ffbd59 !important;
border-radius: 4px !important;
box-shadow: none !important;
color: #254080 !important;
cursor: pointer;
font-family: inherit;
font-size: 1rem;
font-weight: 400;
line-height: 1.4;
text-shadow: none !important;
transition: background .3s linear, border-color .3s linear;
}
.form-all .form-submit-button:hover,
.form-all button[type="submit"]:hover {
background: transparent !important;
border-color: #ff914d !important;
color: #254080 !important;
}
.form-all .form-submit-button:disabled,
.form-all button[type="submit"]:disabled {
cursor: not-allowed;
opacity: .65;
}
/* Keyboard focus */
.form-all input.form-textbox:focus-visible,
.form-all select.form-dropdown:focus-visible,
.form-all textarea.form-textarea:focus-visible,
.form-all input[type="radio"]:focus-visible,
.form-all input[type="checkbox"]:focus-visible,
.form-all .form-submit-button:focus-visible {
outline: 3px solid #115bbd !important;
outline-offset: -3px;
}
/* Validation */
.form-all .form-line-error input.form-textbox,
.form-all .form-line-error select.form-dropdown,
.form-all .form-line-error textarea.form-textarea,
.form-all input.form-validation-error {
border-color: #a21c28 !important;
}
.form-all .form-error-message,
.form-all .form-line-error .form-error-message {
color: #a21c28 !important;
font-size: .8rem;
font-weight: 700;
line-height: 1.4;
margin: .3rem 0 0 !important;
visibility: visible;
}
/* Accessibility: reduced motion */
@media (prefers-reduced-motion: reduce) {
.form-all .form-submit-button,
.form-all button[type="submit"] {
transition: none;
}
}
-72
View File
@@ -1,72 +0,0 @@
# Inactive SOPS/age preparation, 2026-10-30
The owner selected SOPS, age and sops-nix. This directory is a template, not a
host configuration. The development flake remains unchanged. No real recipient,
key, encrypted secret or server user is supplied. No module is deployed.
Official references inspected for this pass:
- [SOPS documentation](https://getsops.io/docs/)
- [sops-nix installation and secret permissions](https://github.com/Mic92/sops-nix)
SOPS encrypts configuration at rest. sops-nix can supply decrypted values at
runtime under `/run/secrets` with explicit owners and modes. This does not make
browser ciphertext or publicly served documents private.
## Owner setup before activation
1. Supply the actual NixOS topology, host flake, deploy user, persisted key
location, backup owner, HTTPS termination and resource-service identity.
2. Pin a reviewed `github:Mic92/sops-nix` input in that host flake; import
`inputs.sops-nix.nixosModules.sops` and the reviewed template. Do not add the
input to the Astro development flake just to evaluate a deployment sketch.
3. The owner generates independent developer/recovery and VPS age identities in
private terminals. Record only public recipients in the reviewed SOPS
creation rule. Use distinct recipients, never a placeholder recipient. Keep
the VPS private identity on persistent root-controlled storage (0600), outside
`/nix/store`, Git, the public static root and CI artifacts.
4. Encrypt the approved credential material using SOPS with both recipients.
Review recipient access, least privilege and an offline recovery copy. SOPS
encrypted files may enter a deployment repository only after owner approval.
5. Set `aia.portalSecrets` options explicitly, then evaluate the complete host
configuration and test decryption on authorized nonproduction infrastructure.
Runtime consumers use the generated `.path`, not Nix evaluation of plaintext.
6. Decide which service reloads after rotation. Rotate application credentials
as well as SOPS recipients when revoking access: rewrapping alone does not
invalidate an already copied password. Test recovery and key restoration.
## Separate staff and management resource authorization
Keep original documents outside Astro `public`, `dist`, release archives and
CDN roots. Proposed delivery namespaces are `/staff-resources/` and
`/management-resources/`; neither is implemented or considered working here.
Use nginx `auth_request` to an approved authorization service or an equivalent
server-enforced policy with individually revocable identities and staff and
management roles. Staff credentials must not authorize management resources;
management access to staff resources must be an explicit policy. Backend file
locations must be internal, inaccessible through static aliases or alternate
paths. Never trust a browser-provided role header.
A separate shared Basic Auth credential file per namespace can be considered
only as an explicitly approved weaker interim model, not identity management or
automatic role inheritance. The template prepares separate secret inputs without
selecting that access model or installing an identity provider.
Use HTTPS, `Cache-Control: private, no-store`, no shared/CDN caching, and
`Referrer-Policy: no-referrer` for protected delivery. Avoid credentials and
sensitive resource paths in access/error logs; review monitoring and backups.
Authorization failures must fail closed, including at proxy/cache boundaries.
Test direct requests, alternate encodings, role crossover and rollback.
## Distinct boundaries and release checks
- SOPS: deployment secrets at rest and controlled runtime access.
- Portal HTML: shared-code browser decryption, offline-guessable access friction.
- Documents: require server authorization even if URLs are encrypted in the UI.
The approved production portal build uses a non-public encrypted two-stream
payload and retains the same browser-side decryption boundary. Approved non-PHI
documents install separately into the VPS-owned staff/management directories;
they are never copied into `dist`. Verify both protected namespaces, two-view
separation, artifact exclusions, code rotation, restore and rollback before
cutover. Revoking a static release cannot retract ciphertext or files already
downloaded by visitors. Site cutover remains separately authorized.
-135
View File
@@ -1,135 +0,0 @@
# Contabo release operations
This site publishes static content through the merged Contabo release manager.
It does not run `nixos-rebuild`, reload nginx, change DNS, or write directly to
`/srv/www/azinstitute4autism.com/www/dist`.
## Required local tools and private inputs
- Node.js 22+, Git, tar, SSH and rsync.
- Either an OpenSSH host alias already configured locally, or a normal SSH
identity accepted by the existing root receiver.
- For environment-only invocations: `AIA_DEPLOY_HOST=administrator@host`,
`AIA_DEPLOY_SSH_IDENTITY=/absolute/path/to/identity`, and
`AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE=/absolute/private/employee-portal/approved-production-ciphertext.json`.
- For positional invocations, use either `SSH_HOST CIPHERTEXT` (OpenSSH resolves
the host alias and identity) or `SSH_HOST SSH_IDENTITY CIPHERTEXT` (the CLI
supplies `-i` and `IdentitiesOnly=yes`).
The payload remains outside Git and the source snapshot. It is browser ciphertext
only; neither access code nor decrypted portal HTML enters an Astro environment
variable, public resource directory, build log, or deployment manifest.
## Commands
From `www/`:
```sh
npm run deploy -- --dry-run
# Use a configured OpenSSH host alias and a private ciphertext path.
npm run deploy -- --dry-run aiar \
"$PWD/private/employee-portal/approved-production-ciphertext.json"
# Supply an explicit SSH identity; paths may contain spaces.
npm run deploy -- --dry-run 'root@66.94.121.180' \
"$HOME/.ssh/AIAMarketing" \
"$PWD/private/employee-portal/approved-production-ciphertext.json"
```
Dry-run performs the local production build, tests, artifact verification,
manifest creation and source-snapshot preparation. With no private production
payload it uses a generated synthetic two-stream fixture and explicitly reports
that the result is not production-ready. It never opens SSH or rsync.
```sh
AIA_DEPLOY_HOST='root@approved-host' \
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE="$PWD/private/employee-portal/approved-production-ciphertext.json" \
npm run deploy -- --confirm
```
The equivalent confirmed positional commands are:
```sh
npm run deploy -- --confirm aiar \
"$PWD/private/employee-portal/approved-production-ciphertext.json"
npm run deploy -- --confirm 'root@66.94.121.180' \
"$HOME/.ssh/AIAMarketing" \
"$PWD/private/employee-portal/approved-production-ciphertext.json"
```
When positional values are present, they take precedence over all three
deployment environment variables. Two positional values deliberately omit
`-i`, allowing the local OpenSSH configuration to select the identity. Dry-run
never opens SSH or rsync, even when host and identity arguments are provided.
Invalid modes, mixed confirmation flags, incomplete positional sets, unsafe
hosts, relative positional paths, and missing ciphertext files fail before a
release can be promoted.
The confirmed command builds with `PUBLIC_ALLOW_INDEXING=true`, Form A live and
the approved live counters configuration, then uploads only fresh commit-specific `staging/source-<sha>` and
`staging/dist-<sha>` directories. It runs, in order:
```text
aia-website-release verify
aia-website-release sync-source
aia-website-release promote
```
The VPS verifies the manifest, promotes an immutable release by atomic symlink,
and retains the prior release. A successful rsync transfer alone is not success.
Rollback requires the reviewed manifest retained at the server’s fixed path:
```sh
AIA_DEPLOY_HOST='root@approved-host' \
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
npm run deploy:rollback -- FULL_APPROVED_SHA --confirm
```
## Employee resources: separate one-time operation
Approved non-PHI employee files are never part of an ordinary release. After
the VPS SOPS-backed Basic Auth material is independently ready:
```sh
npm run deploy:portal-resources -- --dry-run
AIA_DEPLOY_HOST='root@approved-host' \
AIA_DEPLOY_SSH_IDENTITY="$HOME/.ssh/AIAMarketing" \
npm run deploy:portal-resources -- --confirm
```
For the first install, the client extracts `portal-resource-install.sh` from the
current reviewed Git commit, uploads it into the root-controlled commit staging
directory, verifies its SHA-256 remotely, and invokes it through NixOS's base
`/bin/sh` and coreutils path. A prior public site release and a globally installed
Node.js runtime are not prerequisites. It reads only the private collection manifest,
accepts approved `STAFF-INTERNAL` and `MANAGEMENT-INTERNAL` mappings to
`/staff-resources/` and `/management-resources/`, verifies every local hash, rejects links/traversal and
uploads a root-controlled temporary tree. It never uses `--delete` for resource
directories and refuses to replace a different existing file. The VPS installs
regular files as `root:nginx` mode `0640` and reports metadata only.
Local mapping approval authorizes preparation and installation only. After the
authorized VPS rehearsal, verify installed hashes, ownership/mode, staff versus
management Basic Auth, and both protected URLs before deploying portal links.
Before public DNS cutover, test the site with approved host-header/SNI methods,
including the portal’s noindex response, valid ciphertext unlock, both protected
resource namespaces, denial cases, redirects, Form A, IPv4 and IPv6. Portal
shared-code rotation is coordinated: update VPS SOPS inputs and privately
re-encrypt the browser payload together. This interim portal is non-PHI and is
not an employee identity system.
The portal uses one code entry per page session. A successful decrypt retains
the code only in page memory and sends the matching fixed username (`staff` or
`management`) in an explicit same-origin Basic Authorization header when a
protected link is clicked. It downloads the authenticated response as a Blob
and never navigates directly to the protected URL after an error. Verify that
ordinary clicks download without a native credential dialog, inline errors
appear for denied or unavailable files, direct unauthenticated requests remain
401, and neither role can request the other namespace. Reloading, leaving the
page, or an Astro page swap discards the in-memory credential.
-26
View File
@@ -1,26 +0,0 @@
# INACTIVE TEMPLATE. Not imported by the development flake or any deployed host.
# Requires an owner-reviewed sops-nix NixOS module import in the host flake.
{ config, lib, ... }:
let cfg = config.aia.portalSecrets;
in {
options.aia.portalSecrets = {
enable = lib.mkEnableOption "owner-reviewed portal deployment secrets";
encryptedFile = lib.mkOption { type = lib.types.path; description = "SOPS-encrypted YAML only; never a plaintext file"; };
ageKeyFile = lib.mkOption { type = lib.types.str; description = "Private persisted host age key path outside the Nix store"; };
readerUser = lib.mkOption { type = lib.types.str; description = "Approved resource authorization service user"; };
};
config = lib.mkIf cfg.enable {
assertions = [{ assertion = lib.hasPrefix "/" cfg.ageKeyFile && !(lib.hasPrefix "/nix/store/" cfg.ageKeyFile);
message = "The host age identity must be an absolute runtime path outside the Nix store."; }];
sops.defaultSopsFile = cfg.encryptedFile;
sops.age.keyFile = cfg.ageKeyFile;
sops.age.generateKey = false;
sops.age.sshKeyPaths = [];
sops.gnupg.sshKeyPaths = [];
sops.secrets."portal/staff-credentials" = { owner = cfg.readerUser; mode = "0400"; };
sops.secrets."portal/management-credentials" = { owner = cfg.readerUser; mode = "0400"; };
# Consumers reference config.sops.secrets.<name>.path at runtime.
# Do not use builtins.readFile on a decrypted secret, environment.etc.text,
# PUBLIC_* values, or Astro/Vite imports to transport secrets.
};
}
+1636 -2664
View File
File diff suppressed because it is too large. Load diff
+10 -27
View File
@@ -3,48 +3,31 @@
"private": true,
"type": "module",
"engines": {
"node": ">=22.12.0"
"node": ">=20.19.0"
},
"scripts": {
"dev": "astro dev",
"check": "astro check",
"build": "astro check && astro build",
"build:sandbox": "NODE_OPTIONS=--require=./tools/localhost-dns.cjs astro check && NODE_OPTIONS=--require=./tools/localhost-dns.cjs astro build",
"deploy": "node tools/deploy.mjs",
"deploy:rollback": "node tools/deploy-rollback.mjs",
"deploy:portal-resources": "node tools/deploy-portal-resources.mjs",
"portal:prepare": "node tools/employee-portal-migrate.mjs",
"build": "astro build",
"build:sandbox": "NODE_OPTIONS=--require=./tools/localhost-dns.cjs astro build",
"preview": "astro preview",
"extract": "node tools/extract-fallback.mjs",
"extract:full": "node tools/extract-site.mjs",
"extract:blog-footers": "node tools/extract-blog-footers.mjs",
"crawl:live": "node tools/crawl-live-site.mjs",
"audit:links": "node --experimental-strip-types tools/audit-links.mjs",
"audit:links": "node tools/audit-links.mjs",
"audit:images": "node tools/audit-page-imagery.mjs",
"audit:blog": "node tools/audit-blog-content.mjs",
"audit:routes": "node --experimental-strip-types tools/audit-routes.mjs",
"test:routes": "node --experimental-strip-types --test tools/audit-routes.test.mjs",
"test:markdown": "node --test tools/markdown.test.mjs",
"test:publication": "node --experimental-strip-types --test tools/publication.test.mjs",
"test:seo": "node --experimental-strip-types --test tools/seo.test.mjs",
"test:library": "node --experimental-strip-types --test tools/library.test.mjs",
"test:campaign": "node --test tools/campaign.test.mjs",
"test:counters": "node --experimental-strip-types --test tools/counters.test.mjs",
"verify:counters": "node tools/counters-browser.mjs",
"verify:campaign": "node tools/campaign-browser.mjs",
"generate:sitemap": "node tools/generate-sitemap.mjs",
"generate:redirects": "node tools/generate-redirects.mjs"
},
"dependencies": {
"@astrojs/markdown-satteri": "^0.3.5",
"@astrojs/mdx": "^7.0.5",
"astro": "^7.1.5",
"@astrojs/mdx": "^4.3.14",
"astro": "^5.10.0",
"cheerio": "^1.1.0",
"fast-glob": "^3.3.3",
"gray-matter": "^4.0.3",
"swiper": "^12.2.0",
"turndown": "^7.2.0"
},
"devDependencies": {
"@astrojs/check": "^0.9.10",
"typescript": "^6.0.3"
"turndown": "^7.2.0",
"zod": "^3.25.0"
}
}
@@ -1,93 +0,0 @@
Copyright 2017 The Playfair Display Project Authors (https://github.com/clauseggers/Playfair-Display), with Reserved Font Name "Playfair Display"
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -1,93 +0,0 @@
Copyright 2015 The Rubik Project Authors (https://github.com/googlefonts/rubik)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

@@ -1 +0,0 @@
<svg viewBox="113.85996 134.2596 679.2 315.6" xmlns="http://www.w3.org/2000/svg" id="Layer_1" style="max-height: 500px" width="679.2" height="315.6"><defs><style>.cls-1,.cls-2,.cls-3,.cls-4,.cls-5,.cls-6{stroke-width:0px;}.cls-2{fill:#27417f;}.cls-3{fill:#554f62;}.cls-4{fill:#254080;}.cls-5{fill:#aea990;}.cls-6{fill:#f2b85b;}</style></defs><path d="m176.47,162.76l22.18,57.09c.85,2.24,1.83,3.76,2.95,4.54,1.12.79,2.17,1.21,3.14,1.27v1.82c-1.46-.12-3.17-.2-5.14-.22-1.97-.03-3.95-.05-5.95-.05-2.54,0-4.91.01-7.09.05-2.18.03-3.94.11-5.28.22v-1.82c3.09-.12,5.05-.65,5.87-1.59.82-.94.62-2.95-.59-6.04l-16.36-44.17,1.46-1.64-15.09,39.45c-1.09,2.73-1.74,5-1.95,6.82-.22,1.82-.06,3.24.45,4.27.52,1.03,1.41,1.76,2.68,2.18,1.27.43,2.85.67,4.73.73v1.82c-1.82-.12-3.65-.2-5.5-.22-1.85-.03-3.59-.05-5.23-.05-1.46,0-2.74.01-3.86.05-1.12.03-2.14.11-3.05.22v-1.82c1.27-.3,2.55-1.06,3.82-2.27,1.27-1.21,2.48-3.27,3.63-6.18l21.09-54.45h3.09Zm9.54,38.54v1.82h-27.08l.91-1.82h26.18Z" class="cls-2"/><path d="m235.82,179.3c1.76,0,3.26.37,4.5,1.09,1.24.73,2.18,1.65,2.82,2.77.64,1.12.96,2.38.96,3.77,0,1.76-.53,3.26-1.59,4.5-1.06,1.24-2.47,1.86-4.23,1.86-1.51,0-2.8-.46-3.86-1.36-1.06-.91-1.59-2.15-1.59-3.73,0-1.33.35-2.47,1.04-3.41.7-.94,1.5-1.68,2.41-2.22-.6-.49-1.33-.7-2.18-.64-1.64.06-3.15.59-4.55,1.59-1.39,1-2.58,2.27-3.54,3.82-.97,1.54-1.73,3.19-2.27,4.95-.54,1.76-.82,3.4-.82,4.91v20.91c0,2.97.82,4.96,2.46,5.95,1.63,1,3.91,1.5,6.81,1.5v1.91c-1.39-.06-3.38-.14-5.95-.22-2.58-.09-5.28-.14-8.14-.14-2.18,0-4.36.05-6.54.14-2.18.09-3.85.16-5,.22v-1.91c2.37,0,4.04-.45,5.05-1.36,1-.91,1.5-2.64,1.5-5.18v-28.54c0-2.73-.46-4.74-1.36-6.04-.91-1.3-2.64-1.95-5.18-1.95v-1.91c1.94.18,3.82.27,5.64.27,2.06,0,3.99-.11,5.77-.32,1.78-.22,3.44-.53,4.95-.96v10.46c.73-1.76,1.7-3.45,2.91-5.09,1.21-1.63,2.66-2.98,4.36-4.04,1.7-1.06,3.58-1.59,5.64-1.59Z" class="cls-2"/><path d="m264,179.57v39.45c0,2.54.5,4.27,1.5,5.18,1,.91,2.68,1.36,5.05,1.36v1.91c-1.03-.06-2.62-.14-4.77-.22-2.16-.09-4.35-.14-6.59-.14s-4.38.05-6.59.14c-2.21.09-3.86.16-4.96.22v-1.91c2.37,0,4.04-.45,5.05-1.36,1-.91,1.5-2.64,1.5-5.18v-28.54c0-2.73-.46-4.74-1.36-6.04-.91-1.3-2.64-1.95-5.18-1.95v-1.91c1.94.18,3.82.27,5.64.27,2.06,0,3.99-.11,5.77-.32,1.78-.22,3.44-.53,4.95-.96Zm-5.45-21.91c1.88,0,3.45.59,4.73,1.78,1.27,1.18,1.91,2.65,1.91,4.41s-.64,3.23-1.91,4.41c-1.27,1.18-2.85,1.77-4.73,1.77s-3.45-.59-4.73-1.77c-1.27-1.18-1.91-2.65-1.91-4.41s.64-3.23,1.91-4.41c1.27-1.18,2.85-1.78,4.73-1.78Z" class="cls-2"/><path d="m312.54,180.12l-25.09,45.99h8.18c2.42,0,4.58-.49,6.45-1.46,1.88-.97,3.42-2.57,4.64-4.81,1.21-2.24,1.94-5.21,2.18-8.91h2.09c0,4.06.03,7.45.09,10.18s.15,4.97.27,6.73c-2.72-.12-5.54-.22-8.45-.27-2.91-.06-5.79-.09-8.63-.09-3.09,0-6.23.05-9.41.14-3.18.09-6.23.2-9.14.32l25.09-45.99h-8.36c-2.6,0-4.85.5-6.73,1.5-1.88,1-3.35,2.61-4.41,4.82-1.06,2.21-1.74,5.17-2.05,8.86h-2c0-4.12-.03-7.51-.09-10.18-.06-2.66-.15-4.91-.27-6.73,2.67.12,5.45.22,8.36.27,2.91.06,5.82.09,8.73.09s6.14-.05,9.32-.14c3.18-.09,6.26-.2,9.23-.32Z" class="cls-2"/><path d="m340.81,179.3c4.06,0,7.66.85,10.82,2.55,3.15,1.7,5.66,4.36,7.55,8,1.88,3.64,2.81,8.39,2.81,14.27s-.94,10.62-2.81,14.23c-1.88,3.61-4.4,6.24-7.55,7.91-3.15,1.67-6.76,2.5-10.82,2.5s-7.6-.83-10.82-2.5c-3.21-1.67-5.74-4.3-7.59-7.91-1.85-3.61-2.77-8.35-2.77-14.23s.92-10.63,2.77-14.27c1.85-3.64,4.38-6.3,7.59-8,3.21-1.7,6.82-2.55,10.82-2.55Zm0,1.82c-3.15,0-5.73,1.8-7.73,5.41-2,3.61-3,9.47-3,17.59s1,13.95,3,17.5c2,3.55,4.58,5.32,7.73,5.32s5.65-1.77,7.68-5.32c2.03-3.55,3.05-9.38,3.05-17.5s-1.02-13.98-3.05-17.59c-2.03-3.61-4.59-5.41-7.68-5.41Z" class="cls-2"/><path d="m400.07,179.3c2.42,0,4.41.32,5.95.96,1.55.64,2.83,1.5,3.86,2.59,1.09,1.15,1.86,2.64,2.32,4.46.45,1.82.68,4.27.68,7.36v24.36c0,2.54.5,4.27,1.5,5.18,1,.91,2.68,1.36,5.05,1.36v1.91c-1.03-.06-2.64-.14-4.82-.22-2.18-.09-4.33-.14-6.45-.14s-4.11.05-6.14.14c-2.03.09-3.56.16-4.59.22v-1.91c2.06,0,3.51-.45,4.37-1.36.85-.91,1.27-2.64,1.27-5.18v-26.9c0-1.76-.15-3.35-.45-4.77-.31-1.42-.94-2.58-1.91-3.45-.97-.88-2.43-1.32-4.37-1.32-2.24,0-4.23.64-5.95,1.91-1.73,1.27-3.09,3.02-4.09,5.23-1,2.21-1.5,4.68-1.5,7.41v21.91c0,2.54.44,4.27,1.32,5.18.88.91,2.32,1.36,4.32,1.36v1.91c-.97-.06-2.44-.14-4.41-.22-1.97-.09-4.01-.14-6.14-.14s-4.21.05-6.45.14c-2.24.09-3.91.16-5,.22v-1.91c2.37,0,4.04-.45,5.05-1.36,1-.91,1.5-2.64,1.5-5.18v-28.54c0-2.73-.46-4.74-1.36-6.04-.91-1.3-2.64-1.95-5.18-1.95v-1.91c1.94.18,3.82.27,5.64.27,2.06,0,3.99-.11,5.77-.32,1.78-.22,3.44-.53,4.95-.96v9.91c1.57-3.76,3.74-6.39,6.5-7.91,2.75-1.51,5.68-2.27,8.77-2.27Z" class="cls-2"/><path d="m436.06,228.11c-2.54,0-4.73-.49-6.54-1.46-1.82-.97-3.18-2.3-4.09-4-.91-1.69-1.36-3.63-1.36-5.82,0-2.67.6-4.83,1.82-6.5,1.21-1.67,2.77-3.02,4.69-4.04,1.91-1.03,3.94-1.89,6.09-2.59,2.15-.7,4.18-1.36,6.09-2,1.91-.64,3.48-1.38,4.73-2.22,1.24-.85,1.86-1.97,1.86-3.36v-6.18c0-2.18-.35-3.93-1.05-5.23-.7-1.3-1.63-2.22-2.81-2.77-1.19-.55-2.59-.82-4.23-.82-1.4,0-2.88.2-4.46.59-1.57.39-2.81,1.17-3.72,2.32,1.33.37,2.44,1.08,3.32,2.14.88,1.06,1.32,2.38,1.32,3.95,0,1.7-.56,3.03-1.68,4s-2.53,1.45-4.Line truncated

Before

Width:  |  Height:  |  Size: 33 KiB

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" fill="none" stroke="#E5AE56" stroke-width="2">
<path d="m67 13 2-10h22l2 10 13 5 9-6 16 16-6 9 5 13 10 2v22l-10 2-5 13 6 9-16 16-9-6-13 5-2 10H69l-2-10-13-5-9 6-16-16 6-9-5-13-10-2V52l10-2 5-13-6-9 16-16 9 6Z" transform="translate(0 17)"/>
<circle cx="80" cy="80" r="26"/>
</svg>

Before

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

@@ -1,24 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="450" viewBox="0 0 800 450">
<title>نموذج المقدمة والسلوك والنتيجة اللاحقة</title>
<image href="data:image/webp;base64,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 truncated
<rect width="800" height="64" fill="#fbf8ef" />
<g fill="#082f55" font-family="Arial, sans-serif" font-size="25" font-weight="700" text-anchor="middle" direction="rtl">
<text x="132" y="43">المُقدِّمة</text>
<text x="400" y="43">السلوك</text>
<text x="668" y="43">النتيجة اللاحقة</text>
</g>
<g fill="none" stroke="#082f55" stroke-linecap="round" stroke-linejoin="round" stroke-width="4">
<path d="M235 37h60m-12-11 12 11-12 11" />
<path d="M507 37h57m-12-11 12 11-12 11" />
</g>
<rect x="381" y="190" width="50" height="24" rx="3" fill="#fff" opacity=".98" />
<text x="406" y="206" fill="#1f2933" font-family="Arial, sans-serif" font-size="9" text-anchor="middle" direction="rtl">المزيد</text>
<rect x="611" y="190" width="65" height="24" rx="3" fill="#fff" opacity=".98" />
<text x="643" y="205" fill="#1f2933" font-family="Arial, sans-serif" font-size="7" text-anchor="middle" direction="rtl">دقيقتان إضافيتان</text>
<rect x="531" y="351" width="255" height="91" rx="12" fill="#e8efe8" />
<g fill="#082f55" font-family="Arial, sans-serif" font-size="14" direction="rtl" text-anchor="middle">
<text x="658" y="374">◷ حصلتَ على دقيقتين إضافيتين.</text>
<text x="658" y="399">← ثم ينتهي الوقت.</text>
<text x="658" y="424">▣ تستمر خطة «أولًا/ثم».</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

@@ -1,14 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="450" viewBox="0 0 800 450">
<title>طفل يعمل في مساحة هادئة تقل فيها المشتتات</title>
<image href="data:image/webp;base64,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 truncated
<g transform="translate(639 35) rotate(-1 71 87)">
<rect width="142" height="174" rx="3" fill="#eee9d8" stroke="#716b5d" stroke-width="2" />
<g fill="#304c39" font-family="Arial, sans-serif" direction="rtl" text-anchor="middle">
<text x="71" y="31" font-size="17" font-weight="700">ركن الهدوء</text>
<text x="71" y="65" font-size="12">♥ كن لطيفًا</text>
<text x="71" y="95" font-size="12">◯ خذ نفسًا عميقًا</text>
<text x="71" y="125" font-size="12">★ ابذل جهدك</text>
<text x="71" y="155" font-size="12">✓ أنت قادر</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

@@ -1,68 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="533" viewBox="0 0 800 533">
<title>مقارنة بين الهروب من مهمة صعبة واستخدام سلوك بديل لطلب المساعدة</title>
<image href="data:image/webp;base64,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 truncated
<style>
text { font-family: Arial, sans-serif; }
.heading { fill: #092f54; font-weight: 700; }
.body { fill: #202b31; }
</style>
<rect width="800" height="61" fill="#fbf8ef" />
<text class="heading" x="400" y="41" font-size="24" text-anchor="middle" direction="rtl">الموقف نفسه: المهمة صعبة</text>
<rect x="18" y="69" width="91" height="185" rx="12" fill="#c75f45" />
<g fill="#fff" text-anchor="middle" direction="rtl">
<text x="63" y="96" font-size="15" font-weight="700">المسار أ</text>
<text x="63" y="119" font-size="12" font-weight="700"><tspan x="63">استجابة</tspan><tspan x="63" dy="17">غير فعّالة</tspan></text>
<text x="63" y="187" font-size="10"><tspan x="63">تُلبّى الحاجة بطريقة</tspan><tspan x="63" dy="15">لا تساعد الطفل</tspan><tspan x="63" dy="15">على التعلّم.</tspan></text>
</g>
<rect x="111" y="59" width="550" height="29" fill="#fbf8ef" />
<g class="heading" font-size="12" text-anchor="middle" direction="rtl">
<text x="190" y="79">١. تقديم المهمة</text>
<text x="374" y="79">٢. سلوك يعيق المشاركة</text>
<text x="566" y="79">٣. النتيجة اللاحقة</text>
</g>
<rect x="111" y="190" width="550" height="66" fill="#fbf8ef" />
<g class="body" font-size="10" text-anchor="middle" direction="rtl">
<text x="190" y="211"><tspan x="190">تُقدَّم مهمة</tspan><tspan x="190" dy="15">صعبة.</tspan></text>
<text x="374" y="207"><tspan x="374">يدفع الطفل المواد بعيدًا</tspan><tspan x="374" dy="15">للهروب أو التجنب.</tspan></text>
<text x="566" y="203"><tspan x="566">تُزال المهمة أو تتوقف مؤقتًا،</tspan><tspan x="566" dy="14">فيتعزز الهروب ويزداد احتمال</tspan><tspan x="566" dy="14">تكرار السلوك.</tspan></text>
</g>
<rect x="679" y="70" width="103" height="184" rx="12" fill="#f7eadf" />
<g fill="#9c452e" text-anchor="middle" direction="rtl">
<text x="731" y="99" font-size="14" font-weight="700">النتيجة</text>
<text x="731" y="153" font-size="10"><tspan x="731">يلبّي السلوك الصعب</tspan><tspan x="731" dy="15">حاجة الطفل على المدى</tspan><tspan x="731" dy="15">القصير، لكن التعلّم</tspan><tspan x="731" dy="15">لا يتقدم.</tspan></text>
</g>
<rect x="18" y="271" width="91" height="194" rx="12" fill="#3f7a65" />
<g fill="#fff" text-anchor="middle" direction="rtl">
<text x="63" y="298" font-size="15" font-weight="700">المسار ب</text>
<text x="63" y="321" font-size="12" font-weight="700">بديل فعّال</text>
<text x="63" y="388" font-size="10"><tspan x="63">تُلبّى الحاجة نفسها</tspan><tspan x="63" dy="15">بطريقة آمنة وفعّالة</tspan><tspan x="63" dy="15">تدعم التعلّم.</tspan></text>
</g>
<rect x="109" y="245" width="566" height="44" fill="#fbf8ef" />
<g fill="#316b58" font-size="11" font-weight="700" text-anchor="middle" direction="rtl">
<text x="173" y="279">١. تقديم المهمة</text>
<text x="302" y="279">٢. السلوك البديل</text>
<text x="441" y="279">٣. استجابة مفيدة</text>
<text x="593" y="279">٤. النتيجة اللاحقة</text>
</g>
<rect x="110" y="405" width="565" height="68" fill="#fbf8ef" />
<g class="body" font-size="9.5" text-anchor="middle" direction="rtl">
<text x="173" y="427"><tspan x="173">تُقدَّم مهمة</tspan><tspan x="173" dy="14">صعبة.</tspan></text>
<text x="302" y="419"><tspan x="302">يطلب الطفل المساعدة</tspan><tspan x="302" dy="14">ببطاقة أو طلب</tspan><tspan x="302" dy="14">أو إشارة.</tspan></text>
<text x="441" y="415"><tspan x="441">يستجيب البالغ بطريقة داعمة،</tspan><tspan x="441" dy="14">فيقدم المساعدة أو استراحة</tspan><tspan x="441" dy="14">مناسبة حسب الخطة.</tspan></text>
<text x="593" y="415"><tspan x="593">تُلبّى الحاجة ويستطيع الطفل</tspan><tspan x="593" dy="14">المتابعة أو العودة إلى المهمة</tspan><tspan x="593" dy="14">بدعم.</tspan></text>
</g>
<rect x="680" y="272" width="102" height="193" rx="12" fill="#e7f0e8" />
<g fill="#316b58" text-anchor="middle" direction="rtl">
<text x="731" y="301" font-size="14" font-weight="700">النتيجة</text>
<text x="731" y="350" font-size="9.5"><tspan x="731">يساعد السلوك البديل</tspan><tspan x="731" dy="14">على تلبية حاجة الطفل،</tspan><tspan x="731" dy="14">فيزداد احتمال استخدامه</tspan><tspan x="731" dy="14">مجددًا ويتقدم التعلّم.</tspan></text>
</g>
<rect x="136" y="476" width="558" height="50" rx="12" fill="#e5edf3" />
<g fill="#173b5b" text-anchor="middle" direction="rtl">
<text x="415" y="497" font-size="13" font-weight="700">التعزيز الفعّال يجعل استخدام المهارة البديلة مجديًا.</text>
<text x="415" y="516" font-size="10">عندما يُعزَّز السلوك البديل، يصبح الخيار الأسهل والأكثر فاعلية.</text>
</g>
<rect x="305" y="347" width="49" height="25" rx="2" fill="#fff" />
<text x="329" y="364" fill="#253238" font-size="8" text-anchor="middle" direction="rtl">مساعدة</text>
</svg>

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

+3
View File
@@ -0,0 +1,3 @@
User-agent: *
Allow: /
Sitemap: https://www.azinstitute4autism.com/sitemap.xml
+100
View File
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>https://www.azinstitute4autism.com/</loc></url>
<url><loc>https://www.azinstitute4autism.com/aba-therapy</loc></url>
<url><loc>https://www.azinstitute4autism.com/aba-therapy-intake-process</loc></url>
<url><loc>https://www.azinstitute4autism.com/about</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library/aba-school-readiness-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library/autism-self-advocacy-skills-aba</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library/behavior-management-functions-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library/executive-functioning-skills-autism</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library/first-then-cards-autism-transitions</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library/positive-reinforcement-techniques</loc></url>
<url><loc>https://www.azinstitute4autism.com/ar/library/proactive-reactive-aba-strategies-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/autism-evaluations</loc></url>
<url><loc>https://www.azinstitute4autism.com/careers</loc></url>
<url><loc>https://www.azinstitute4autism.com/client-consultation</loc></url>
<url><loc>https://www.azinstitute4autism.com/client-forms</loc></url>
<url><loc>https://www.azinstitute4autism.com/contact</loc></url>
<url><loc>https://www.azinstitute4autism.com/donate-autism-giveback</loc></url>
<url><loc>https://www.azinstitute4autism.com/employee-portal</loc></url>
<url><loc>https://www.azinstitute4autism.com/es</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/aba-therapy</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/aba-therapy-intake-process</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/autism-evaluations</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/client-consultation</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/contact</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/learner-social-club</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/aba-school-readiness-arizona</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/autism-evaluation-diagnosis-arizona-parent-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/autism-evaluation-what-to-expect</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/autism-family-self-care-tips</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/autism-self-advocacy-skills-aba</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/emotional-regulation-aba</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/enhancing-generalization-skills</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/executive-functioning-skills-autism</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/first-then-cards-autism-transitions</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/parents-guide-to-autism-and-aba</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/positive-reinforcement-techniques</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/library/social-pragmatic-communication-autism</loc></url>
<url><loc>https://www.azinstitute4autism.com/es/services</loc></url>
<url><loc>https://www.azinstitute4autism.com/faqs</loc></url>
<url><loc>https://www.azinstitute4autism.com/insurance</loc></url>
<url><loc>https://www.azinstitute4autism.com/learner-social-club</loc></url>
<url><loc>https://www.azinstitute4autism.com/library</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aac-visual-supports-autism</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aba-school-readiness-arizona</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aba-school-readiness-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aba-therapy-benefits</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aba-therapy-dtt-net-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aba-therapy-prompting-parenting-benefits</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aba-therapy-summer-routine-tips</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aba-toilet-training-child-autism</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/aia-world-autism-community-day-celebration</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/asd-sensory-friendly-recipe-thanksgiving-pumpkin-cake</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/asd-sensory-friendly-recipes-pancakes</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/autism-evaluation-diagnosis-arizona-parent-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/autism-evaluation-what-to-expect</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/autism-fall-break-routine-tips-halloween-thanksgiving</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/autism-family-self-care-tips</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/autism-friendships-social-play-support</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/autism-self-advocacy-skills-aba</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/autism-therapy-rapport-strategies</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/behavior-management-functions-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/behavior-modification-techniques-reinforcement-theory</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/communication-social-skills-autistic-children-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/community-highlight-meet-rula-diab</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/critical-thinking-skills</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/early-signs-autism-by-age</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/emotional-regulation-aba</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/enhancing-generalization-skills</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/executive-functioning-skills-autism</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/first-then-cards-autism-transitions</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/heart-full-of-gratitude</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/individualized-aba-therapy</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/integrated-aba-model-announcement</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/managing-aggressive-behavior-outbursts</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/meet-rula-diab-bcba</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/new-aia-scottsdale-office</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/new-year-2024-autism-holiday-tips</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/new-year-goals-2023</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/november-2022-aia-update</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/parents-guide-to-autism-and-aba</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/play-leisure-skills</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/positive-reinforcement-techniques</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/proactive-reactive-aba-strategies-guide</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/reduce-behavior-management</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/repetitive-behavior</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/sensory-processing</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/social-pragmatic-communication-autism</loc></url>
<url><loc>https://www.azinstitute4autism.com/library/understanding-autism-support</loc></url>
<url><loc>https://www.azinstitute4autism.com/privacy-policy</loc></url>
<url><loc>https://www.azinstitute4autism.com/referrals</loc></url>
<url><loc>https://www.azinstitute4autism.com/schedule-consultation</loc></url>
<url><loc>https://www.azinstitute4autism.com/services</loc></url>
<url><loc>https://www.azinstitute4autism.com/team</loc></url>
<url><loc>https://www.azinstitute4autism.com/tour</loc></url>
</urlset>
-533
View File
@@ -1,533 +0,0 @@
# AIA Astro Migration — Living Session Handoff
## Deployment and employee-portal release preparation — 2026-11-04
The clinical director has accepted the collected non-PHI employee portal views,
their interim shared-code presentation and the approved employee resources.
This supersedes earlier collection/content-acceptance tasks. Deployment,
filesystem permissions, protected-resource authorization, DNS and cutover remain
separate technical gates.
The site-side deployment workflow builds an indexing-enabled release with an
explicit non-public approved portal ciphertext input, validates the artifact and
Contabo-compatible manifest, uploads only commit-specific staging trees, then
uses `aia-website-release verify`, `sync-source`, and `promote`. It does not
rebuild NixOS or alter nginx. Employee documents are a separate owner-run,
hash-verified resource-installation operation into the VPS-owned protected
namespaces. See [the release runbook](../integrations/nixos/deploy.md).
The browser payload remains ciphertext only; codes, plaintext portal content,
private manifests and resources must never enter Git, `dist`, source snapshots,
logs or deployment manifests. `/employee-portal` remains noindex and excluded
from sitemap/hreflang. Form A, referral and publication behavior are unchanged.
### Portal resource preparation correction — 2026-11-04
The resource schema now separates approved source-to-role mapping from actual
VPS installation evidence. An approved mapping may be prepared and installed
while all server-installed/hash/permission/authentication/URL verification flags
remain false. Shared resources can be installed from one verified source into
both protected namespaces without weakening management isolation. The owner-only
private workflow identifies the two encrypted streams via hidden prompts,
derives deterministic role mappings, rewrites all legacy employee `/hubfs/`
links, and creates a hash-bound private readiness record. A real production
ciphertext cannot pass `npm run deploy -- --dry-run` merely because it is
structurally valid.
The first resource install no longer depends on a previously promoted site
release: the reviewed POSIX installer is staged from the exact Git commit and
verified by SHA-256 before root execution. Server installation, SOPS-backed
Basic Auth and protected URL verification remain future VPS-rehearsal gates.
## Current referral decision — 2026-11-01 (supersedes Form C planning)
The owner directs `/referrals` to retain the current public-site workflow: one
button-styled **Refer a Client** link to
[the existing hosted Jotform](https://form.jotform.com/231638510219149). There is **no separate Form C**
to create, embed, configure or launch. The former Form C / proposed two-form
architecture is historical only. `/referrals` renders no local form or Form A
iframe; the original 16 approved Form A placements remain unchanged.
This is authorization to restore the existing destination in Astro, **not**
verification of that separate legacy Jotform's HIPAA configuration, notification
recipients, patient-data handling, accessibility or continued operational
suitability. Review the actual hosted form and its clinical/privacy claims before
production cutover. No account modification or submission occurred in this PR.
**Last updated:** November 1, 2026 (UTC)
**Repository:** `AIAMarketing/azinstitute4autism.com`
**Working branch:** `faithful-astro-migration`
**Last pushed checkpoint:** `55adb797051473c3067a0d454515153237e9b8d6` — completion handling and portal styling. The new commit containing this handoff simplifies Form A to default-live without rewriting that history.
**Previous accepted checkpoint:** P9-03 documentation, signed `537f9864a0a3d0806180cbeca909bf1d03200c6f`
**Implementation checkpoint:** the commit containing this handoff update; obtain its actual SHA from Git history after the signed checkpoint is created.
**Next milestone:** continue Phase 9 owner decisions and authorized integration batches; then Phase 10 — Final QA/Cutover Readiness.
The landing-page migration is technically completed for checkpoint purposes.
Editorial, accessibility, stakeholder and production-release approval remain
separate. This handoff does not authorize deployment or integration activation.
## Current decision — 2026-10-30: default-live Form A
The owner intentionally supersedes the earlier isolated-test and seven-route
production-gate architecture. `npm run dev` and `npm run build` now enable Form A
on exactly **16 approved placements**, including the publicly reachable
`aia.web3app.dev` environment. No additional approval flags or access restriction
are required. `PUBLIC_AIA_FORMS_MODE` is optional: absent/empty means `live`;
explicit `off` and `mock` remain available. Invalid/obsolete `isolated-test`
settings produce an actionable configuration error. The former approval flags
and form environment role are retired, not renamed.
Indexing and forms are independent. Both publication modes emit ten immediate
frames (two contact, five landing, three consultation) and six deferred bilingual
service-drawer frames. The bounded registry fixes ID `262946078314059`, HTTPS
origin, context and language. Form B is retired; Form C is canceled by the November 1 referral decision.
Live drawers retain four-second/50%-scroll opening, shared 30-day suppression,
manual CTA override, deferred loading, verified completion acknowledgment for
five seconds, animated dismissal and fresh-form reopening. Off mode does not
automatically show inactive drawers. All iframe security/fallback behavior is
preserved. Employee-portal preview remains independently gated by explicit local
approval, valid private ciphertext input and non-indexing output; Form A cannot
authorize private content. No portal private resources enter normal artifacts.
This owner authorization does not modify Jotform, authorize site cutover or
complete pending consultation-language, provider-event, accessibility, runtime
telemetry/privacy, recipient-routing or hosting acceptance. See the
[current operating guide](../integrations/jotform/README.md) and
[implementation and validation report](phase-9-form-a-default-live-2026-10-30.md).
Earlier dated decisions and test results below are historical evidence, not
current environment setup instructions.
## Latest verified validation — 2026-10-30 default-live revision
206 tests pass; Astro check has zero diagnostics. Normal default-live staging:
128 routes, empty sitemap, zero hreflang, ten immediate plus six deferred Form A
frames. Indexing-enabled: 127 routes, 109 sitemap URLs, 180 hreflang links, the
same 16 placements. Explicit off/mock artifacts contain no real Form A frames.
Guarded browser regressions preserve drawer completion/suppression and portal
fixture behavior; 128/128 staging routes open. Link/image/blog audits have zero
findings. See the current default-live report for exact overlapping check counts,
network interception evidence and remaining owner acceptance. No deployment,
Jotform mutation or new real submission was performed.
## Authority and checkpoint history
Read repository-root `AGENTS.md`, `MIGRATION_BRIEF.md` and `AUTONOMOUS-CODEX.md`,
then this handoff and the relevant [migration summary](migration-summary.md).
Later Phase 6A ratification controls conflicting original recommendations.
- Phase 5C Team: `34d5394b3ce765028a27b9cddd9952de3f09bfe7`.
- Phase 6A proposal: `76a035424dc5245443476b168d8c91ea62eed27b`.
- Phase 6B.1 search: `b20c253383440598c2d07bf6f852906ac00c42df`.
- Phase 6B.2 pagination: `6f5ac3c0d233cee5fbbb62be79bc6909e6bec183`.
- Phase 6B.3 author archives: `8646792d46a8a117ef617f5dd2582c2550b45d19`.
- Phase 6B.4 URL/SEO: `8192ea71c47a7163b40a7fad144ebbd2523282d1`.
- Phase 6B.5 multilingual navigation/RTL: the signed replacement checkpoint
`a699d467f19fafbfdda5fce1ce6226baa6e5fc3c`; do not use its superseded unsigned SHA.
- Phase 6C Library/multilingual parity: signed checkpoint
`b5bc95bc2b8e36c58e8b4d8ab4b11391374a7883`.
- Phase 7 multilingual reconciliation: signed checkpoint
`8e64d322092b1fa6e0f648ddf26a665c80588198`.
- Phase 8 visual/accessibility implementation: signed checkpoint
`59911eb929579af7bcd6c42de6476128dab62289`.
- P9-03 Jotform contract and complete owner inventory: signed checkpoint
`537f9864a0a3d0806180cbeca909bf1d03200c6f`.
- Phase 9 landing-page integration: the commit containing this handoff update;
obtain its actual SHA from Git history. It does not resolve P9-01 through P9-10.
Phase 6B.5 visitor navigation remains independent of SEO hreflang. Published
locale destinations, explicit fallback notices, native language disclosure,
Arabic contact bidi isolation and the two-line shared address remain intact.
`/ar` remains unpublished with an explicit English-home fallback.
ContactObfuscation is unchanged; reversed no-JavaScript strings are intentional.
The earlier Phase 6B.5 manual acceptance does not cover subsequent Phase 6C work.
## Completed Phase 6C technical sequence
- **6C:** restored nine missing English articles and source-backed self-hosted
media; derived English Library and author page 6 from the catalog.
- **6C.1:** restored source-supported Halloween contextual links in English
self-advocacy and AAC articles.
- **6C.2:** reconciled three materially outdated English articles and current
published Spanish school readiness; replaced the obsolete Arabic
antecedent/consequence body with a complete translation; audited all 19
established translation relationships.
- **6C.3:** reconciled featured-image alternatives, source-supported headings,
truncated descriptions and supported modification dates; retained the new
Arabic guide's intentional modification-date omission; localized three diagrams.
- **6C.4:** reconciled contextual and external links, previous/next/related
relationships, image links and fragments; added localized self-advocacy
Halloween references while preserving the landing-page ownership gate.
- **6C.5:** audited all 74 articles, corrected narrow structural/accessibility
regressions, and verified metadata, links, FAQs, translation relationships,
pagination, search and publication policies. Technical readiness has
documented nontechnical release gates.
Detailed evidence and reviewer checklists are in the
[final acceptance report](phase-6c5-final-library-acceptance-2026-10-13.md).
The [checkpoint manifest](phase-6c5-checkpoint-manifest-2026-10-13.md) lists 148
implementation/evidence paths; that checkpoint included its handoff as path 149.
Historical phase records retain their original context.
## Completed Phase 7 technical sequence
- Recovered Spanish privacy policy with February 19, 2025 revision date,
localized metadata and reciprocal English/Spanish policy navigation.
- Localized actual Spanish form labels, options, instructions, disabled notices
and Contact map text using explicitly passed publication locale; no backend enabled.
- Translated the Spanish reinforcement tip without changing article identity,
dates or surrounding content; fluent/clinical approval remains pending.
- Localized Spanish/Arabic author headings and isolated Arabic BCBA/LBA text;
biographies, identities and archive SEO unchanged.
- Prepared the [nonproduction verification plan](phase-7-nonproduction-verification-plan-2026-10-14.md)
and [Phase 9 decision register](phase-9-decision-register-2026-10-14.md).
P9-01 through P9-10 all remain **Pending decision**.
See the [Phase 7 reconciliation report](phase-7-multilingual-reconciliation-2026-10-14.md)
and [checkpoint manifest](phase-7-checkpoint-manifest-2026-10-14.md).
The non-Library matrix excludes all three Library-root content records:
20 EN / 8 ES / 1 unpublished AR draft → 20 EN / 9 ES / 1 unpublished AR draft;
28 → 29 eligible pages and 8 → 9 English–Spanish pairs. The final matrix has
30 records including the draft. Whole pages-collection counts (including roots)
are 21/9/2 → 21/10/2, with 9 → 10 English–Spanish pairs. Do not mix populations.
## Completed Phase 8 technical sequence
- Static checks and guarded Chromium smoke covered all 122 generated routes.
The original browser pass captured 50 desktop/50 mobile full pages, checked
50 routes without JavaScript, and passed 40 focused interactions, with one
native-dialog review finding subsequently compared against a native control.
- Corrected prose/FAQ/contact/form link contrast and underlines, navigation,
language-menu, skip-link, byline and diagram focus treatments; fixed the
scoped homepage director-grid overflow at 320px.
- Localized Arabic article controls and bidi counts without changing the API
script. Corrected DTT/NET peer sections and consultation heading semantics
while preserving text, fragments and appearance. Native dialogs remain intact;
Chromium's browser-chrome boundary did not establish application focus escape.
- Corrected Phase 7 carryovers: Spanish HSA/FSA section after ESA/before financial
help, Spanish alternative text and APROBADO artwork; Spanish privacy's missing
information-collection H2 (eleven sections/four items), with no legal-text change.
The final Spanish badge preserves the original alpha and every pixel outside
its lettering rectangle; the English artwork is unchanged.
- Replaced flattened Tour Markdown with one MDX publication, structured nine-photo
data and accessible carousel: captions, thumbnails, wraparound, keyboard/focus,
restrained announcements, no auto-rotation, full no-JavaScript fallback and
restored consultation link. No new dependency or production integration.
- Bounded follow-up: 30 grouped Chromium checks. Consolidated pass: 21 grouped
checks, two contrast/reduced-motion probes, five distinct routes, 20 full-page
captures, native 200% zoom on Tour/privacy (26 overlapping frames), four crops.
Earlier follow-up also tested seven routes at native 200% zoom. Badge correction:
eight EN/ES checks/crops at 320/390/768/1440px. These are distinct evidence
populations, not additional unique-site-route totals.
- Loopback-only contexts allowed only local GET/HEAD, blocked external traffic,
WebSockets and website service workers. Map-resource attempts and a synthetic
fixture POST were prevented; no production API/like/form/conversion request
was transmitted. Disabled controls/noindex remain insufficient API isolation.
See [consolidated findings](phase-8-consolidated-followup-2026-10-15.md),
[browser results](phase-8-browser-verification-2026-10-15.md),
[badge correction evidence](phase-8-badge-correction-evidence-2026-10-15.json),
and the [Phase 8 checkpoint manifest and validation](phase-8-checkpoint-manifest-2026-10-15.md).
Historical failed browser attempts remain recorded. System Playwright 1.61.0 /
Chromium 151.0.7922.75 now work; the optional Nix browser-shell realization is
not independently verified. No real screen-reader session or owner sign-off occurred.
Tour's public source passed normal TLS but was cache-qualified. Spanish privacy's
capture used a certificate-insecure fallback after validation failed. Neither
establishes current origin freshness; Spanish policy additionally requires a
trusted-source comparison. No insecure retrieval was repeated.
## Completed Phase 9 landing-page integration
- Imported four independently styled campaign routes from the sibling landing-page
repository: `/lp/aba-therapy`, `/lp/aba-insurance`, `/lp/aba-ahcccs` and
`/lp/aba-private-pay`. Their local fonts, images, components, metadata and
source noindex policy are isolated from ordinary site pages.
- Migrated the branded public `/lp/early-intervention` route with its compact
header/footer, source section order, existing byte-identical local imagery and
cache-qualified source evidence. It is self-canonical and adds one sitemap URL.
- Omitted the sibling project's API, tracking, success-state and attribution
runtime. Normal staging and indexing artifacts keep all five lead panels inactive,
with no native POST, live Jotform or conversion behavior. The later seven-route
Form A isolated-test adapter is separately gated and remains outside those artifacts.
P9-01, P9-03, P9-05 and P9-07 remain open.
- Added `/lp` as a temporary staging/testing index linking the five pages. It is
always `noindex,nofollow`, sitemap/hreflang-excluded and omitted entirely when
`PUBLIC_ALLOW_INDEXING=true`. This build gate is not access control.
- Detailed evidence is in the
[integration report](phase-9-campaign-page-integration-2026-10-20.md),
[sanitized evidence JSON](phase-9-campaign-integration-evidence-2026-10-20.json),
[early-intervention source record](phase-9-early-intervention-source-2026-10-20.json)
and [final offline reconciliation](route-reconciliation-2026-10-20-offline-18-37-43-828Z.json).
Earlier October 20 reconciliations remain superseded local evidence outside
the checkpoint.
### Current two-form status — 2026-10-29
- Form A uses one 16-placement live registry: two contact, five landing, three standalone consultation and six EN/ES service drawers. Mode defaults to live; off/mock are explicit options. `/referrals` independently links to the owner-approved existing hosted Jotform; Form C creation is canceled. See the November 1 decision above.
- Owner-confirmed direct-Jotform evidence covers synthetic EN/ES submission, native thank-you, conditional email/language, generic no-answer/no-PDF staff notification, autoresponder delivery, corrected fixed Reply-To, no webhooks/integrations, privacy scope, recipient access and retention. The owner also reports successful Astro-iframe synthetic submission and confirmation on English contact, Spanish contact and one ABA landing placement; record the exact third route before release. Functional submission acceptance is complete only for those owner-reported samples. All-sixteen-route accessibility, runtime-network/telemetry, deployment and site-release acceptance remain open.
- The adapter retains fixed URLs, responsive fixed heights, `no-referrer`, `allow-forms allow-scripts allow-same-origin`, no helper script, and a hosted fallback that is hidden without space until a 15-second missing-load timeout. A frame load only clears that timeout; it does not prove cross-origin application health or accepted submission. The official Jotform resizing handler is conditionally acceptable pending separately authorized source, origin, privilege, Firefox and error-state verification; it is not implemented. Fixed heights remain current.
- No additional Form A approval/environment flags remain. Indexing does not authorize or disable forms. Marketing-only notification routing remains a pre-cutover operational check. Rollback requires explicit mode `off`, rebuild and artifact verification; merely removing the mode restores live. No Form C is needed. Counters, analytics and API forwarding remain inactive.
The indexing-enabled build has 127 HTML routes/canonicals and 109 sitemap URLs.
Normal staging has 128 `noindex,nofollow` pages because it also contains `/lp`;
its sitemap and hreflang are empty. Existing 180 hreflang links across 55 routes,
25 translation sets, 74 Library articles, nine author archives and nine redirect
definitions are unchanged. Guarded Chromium covered the four campaign routes at
320/390/768/1440px, the branded route at those widths plus no-JavaScript checks,
and `/lp` at 320/1440px. Real screen-reader, non-Chromium and authorized visual,
clinical, privacy and organizational acceptance remain pending.
## Verified technical baseline
| Metric | Result |
|---|---:|
| Library articles / locale search records | 55 EN / 12 ES / 7 AR = 74 |
| Indexing-enabled HTML routes / unique canonical targets | 127 / 127 |
| Normal staging HTML routes, including temporary `/lp` | 128 |
| Author archive routes | 9 |
| Indexing-enabled sitemap URLs | 109 |
| Hreflang links / participating routes | 180 / 55 |
| Validated page/article translation sets | 25 |
| Repository redirect definitions | 9, not activated on deployed hosts |
| Visible/schema-aligned FAQ answers / articles | 182 / 30 |
English Library and author pagination is `10/10/10/10/10/5`; Spanish is `10/2`,
Arabic is one seven-article root. Page 6 is derived, with no page 7 or page-one
HTML alias. Search remains locale-scoped, metadata-only and demand-loaded.
Publication ordering uses original dates, not modification dates. Existing
syndicated external-canonical/noindex exceptions remain unchanged.
Normal staging output is **128 `noindex,nofollow` HTML pages, an empty sitemap
and no hreflang**. Indexing-enabled validation is local only. No deployment,
redirect activation, form submission or production integration is authorized.
Final source-matching offline evidence is the
[October 20 reconciliation](route-reconciliation-2026-10-20-offline-18-37-43-828Z.json):
138 dispositions, 128 local generated routes, 70 reused historical production
requests and schema 2. Use this explicit evidence path for read-only checks.
Earlier Phase 8 and October 20 reports remain historical evidence, not the
current source fingerprint. No fresh production crawl was performed.
The historical Phase 6C.5 parity classifications were 10 confirmed, 58 with accepted intentional
deviations, one minor discrepancy, five requiring human review, zero material
discrepancies and zero insufficient-verification records against the selected
evidence. Findings rely on dated, sometimes cached/prerendered public HubSpot
representations; they do not establish independent current origin freshness.
The newer Arabic antecedent/consequence translation intentionally supersedes
its outdated public Arabic body. Machine-assisted work is not professional approval.
Phase 8 checkpoint preparation revalidation on October 15 passed sequentially
with `TMPDIR=/tmp`: Astro check (101 files, zero diagnostics), Markdown 20,
publication 33, SEO 35, **Library 53**, routes 10 and Phase 8 5 tests: **156 total**.
Both build modes and link/image/blog audits pass. The final normal staging build
and explicit offline consistency check retain the publication safeguards above.
Git identity/signing remains the user’s host-terminal responsibility.
## Outstanding Stakeholder Review and Production Release Gates
- **Clinical/organizational — AIA:** approve eligibility and program-specific
ranges against general ABA eligibility of **18 months through eight years**;
resolve the summer-routine age discrepancy. Review Preparatory Academy ages
2–6 and 1:2 delivery ratio, ABA versus education, Arizona educational guidance,
functional assessment, behavior intervention, reinforcement, extinction,
aggression, self-injury, safety, treatment/outcome claims and author roles,
credentials and biographies, including Arabic physician-like wording versus
English “clinician.” Source publication alone is not clinical approval.
- **Fluent Spanish/Arabic and clinical review:** revised Spanish school readiness,
rewritten Arabic antecedent/consequence guidance and terminology, all three
localized Arabic diagrams, localized self-advocacy Halloween additions,
operational labels and cross-language notices remain pending.
- **Spanish tip review:** Phase 7 corrected the English tip at
`/es/library/positive-reinforcement-techniques`. Its fluent-Spanish and
clinical/editorial acceptance remains open; historical Phase 6C findings remain intact.
- **Privacy/legal and trusted-source approval — P9-07:** both policy claims need
AIA privacy/legal approval. Spanish privacy was recovered from a cache-qualified
response after standard TLS certificate validation failed; fallback disabled
certificate verification. Matching captured text does not prove authenticated
origin fidelity. Before production, compare against a certificate-validated
source or owner-supplied authoritative export with provenance; no trusted
comparison is available yet. Fluent Spanish approval remains mandatory.
Do not repeat insecure retrieval or rewrite policies to hide this limitation.
- **Browser/accessibility:** guarded Chromium automation now covers desktop/mobile,
keyboard, no-JavaScript, RTL/diagram scrolling and actual 200% zoom. Authorized
visual/source-fidelity acceptance, non-Chromium coverage, native-dialog AT
behavior, Arabic visual-language acceptance and real screen-reader testing
remain pending. Earlier failed attempts remain historical; browser automation
and DOM inspection do not constitute reviewer or assistive-technology approval.
- **Spanish HSA/FSA financial claims:** fluent-Spanish and organizational/financial
review of wording, account use, pre-tax and tuition claims remains pending.
Localized artwork is not financial eligibility or reimbursement approval.
- **Landing-page integration — Phase 9 owner gate:** presentation for the four
campaign routes and `/lp/early-intervention` is now imported under explicit
owner authorization. The Library CTA remains provisionally
`/client-consultation`; its equivalence to `/lp/early-intervention`, campaign
routing, redirects and live form behavior are not approved. Do not activate
submissions or production redirects without separate authorization.
- **Employee portal — P9-02:** staff/management access separation, authentication,
authorization and employee/clinical data security remain unresolved; current
metadata-only route is not a completed portal. See the
[portal brief](employee-portal-migration-brief-2026-10-08.md).
- **Likes/views API — P9-04:** the uncommitted local implementation now defaults
to explicit fail-closed `off`, with deterministic local `mock` behavior and
no live adapter. A future live adapter still requires separate API-origin,
credential, cookie, consent and production-approval evidence.
- **Author SEO:** keep archives self-canonical, `noindex,follow` in indexing-enabled
builds, sitemap-excluded and hreflang-excluded. Changes require explicit approval.
- **Forms/privacy/analytics/advertising:** approve form destinations and submission
APIs, HIPAA/privacy safeguards, consent/analytics, Google Ads conversion tracking
and each production integration's activation. No new PHI flow is authorized.
- **Hosting/release:** separately verify Contabo/NixOS deployment assumptions,
HTTPS, canonical host, slashless URLs, query preservation, redirect targets and
loops, real 404 responses, asset delivery, sitemap/robots, reproducible deployment,
rollback and organizational release approval. The temporary Docker/nginx
trailing-slash HTTPS-to-HTTP-to-HTTPS chain remains explicitly deferred.
Static-build success does not verify these deployed behaviors.
## Uncommitted extended Phase 10 technical QA — 2026-10-22
The signed baseline remains `e874b26bb9dc24beb6bce2e83a10e7800e7e12b9` on
`faithful-astro-migration`; this section records uncommitted verification and
must not be treated as an accepted checkpoint. The local Phase 9 batches for
counter isolation, off/mock form infrastructure and Contabo release planning
were revalidated. Two bounded responsive defects were corrected: mobile
PageHero headings now fit their available width, and the Library two-column
grid allows its primary track to shrink at tablet width.
The final guarded Chromium pass opened 128/128 staging routes. The responsive
matrix passed 110/110 checks across 22 routes at 320/390/768/1024/1440px.
Four Leaflet GET requests were intercepted before transmission; no production
API, Jotform, Contabo form, analytics, advertising or WebSocket request was
transmitted. The normal staging artifact has 128 noindex,nofollow pages, an
empty sitemap and zero hreflang; the indexing artifact has 127 pages, 109
sitemap URLs and 180 hreflang links, with the temporary `/lp` review index
excluded.
New local verification tools and reports are described in the Phase 10 audit,
browser, release-rehearsal and technical-readiness reports. A loopback Node
release rehearsal passed atomic switch and rollback. nginx, Contabo topology,
real screen-reader, non-Chromium, fluent-language, clinical, privacy/legal and
all P9 owner decisions remain pending. No checkpoint SHA is assigned to this
uncommitted work; the next signed SHA must come from the user's Git history.
## Next: Phase 9 — Human-Decision Gates
Begin from the commit containing this handoff update; obtain its actual SHA from
Git history and verify branch, history and working tree. Review
[P9-01 through P9-10](phase-9-decision-register-2026-10-14.md)
and gather evidence/owner decisions before proposing bounded implementation:
landing-page ownership; portal security/access; forms/APIs; likes/views isolation;
analytics/consent/Ads; clinical/organizational claims; policy/legal/provenance;
author SEO; hosting/rollback; production authorization. All ten remain **Pending decision**.
Do not infer approval from a technically feasible option or this checkpoint.
Use the [nonproduction plan](phase-7-nonproduction-verification-plan-2026-10-14.md)
and [reviewer procedure](phase-8-host-browser-verification-2026-10-14.md) for remaining
human acceptance. No hosted preview before approved fail-closed integration
isolation. Phase 10 retains final QA, deployed routing/integration tests,
rollback rehearsal and cutover readiness. Neither phase is authorized for live
changes by this handoff. The user separately authorizes each implementation scope.
## Working protocol and protected local files
Preserve the Markdown-first manifest-driven architecture, explicit translation
relationships and ratified publication policies. Implement only authorized scope;
report evidence and structural diffs before checkpoint actions. Follow
`AUTONOMOUS-CODEX.md`; do not repair identity/signing or bypass sandbox restrictions.
Do not read, modify, move, delete, stage or checksum root `merge-plan.md`.
### Reconciliation archive — 2026-10-28
The owner explicitly superseded the former local-preservation instruction for
the seven untracked reconciliation artifacts below. They were all confirmed
untracked and moved, without overwrite, to the local archive outside this Git
repository:
`/home/alice/projects/wrk/aia/local-archives/azinstitute4autism-route-reconciliation-2026-10-28`
- `route-reconciliation-2026-10-11-offline.json`
- `route-reconciliation-2026-10-12-offline.json`
- `route-reconciliation-2026-10-13-offline.json`
- `route-reconciliation-2026-10-13-offline-06-16-06-857Z.json`
- `route-reconciliation-2026-10-20-offline.json`
- `route-reconciliation-2026-10-20-offline-18-04-39-776Z.json`
- `route-reconciliation-2026-10-22-offline.json`
They remain excluded from Git because they are superseded intermediate or
local-only evidence. Filename-reference review found historical report links
only; no runtime, test, build or audit dependency. The tracked final evidence
remains `route-reconciliation-2026-10-20-offline-18-37-43-828Z.json` and
`route-reconciliation-2026-10-22-offline-05-10-47-827Z.json`. Historical
reports may retain filename references as their contemporaneous record; no
active dependency remains unresolved. The four October 11–13 files were moved
under this explicit authorization without parsing or checksumming their
contents.
Exclude root `merge-plan.md` and temporary `.phase8-stage-paths.nul` as well.
The old `.phase7-stage-paths.nul` is absent; do not recreate it.
The staging aid is for the user's host terminal only; never stage it or use a
broad Git add. The actual future checkpoint SHA comes from Git after the user
signs; do not amend merely to insert it here.
## Consolidated service drawers and portal checkpoint, 2026-10-30
This section supersedes earlier explicit-only drawer behavior. The checkpoint
containing this update adds four-second/50%-scroll consultation opening, one
shared 30-day localStorage expiry preference, manual override through the six
existing EN/ES service CTAs, and typed bilingual service introductions. The
Academy configuration is prepared without a new page. The fixed seven production
and separate nine consultation-test route lists remain unchanged. Consultation
indexing approval must explicitly be `false`.
The employee route now has a locked, local-decryption UI and a private owner-run
collection/rewrite utility. Real passphrases were unavailable: real portal
content/resource inventory and collection remain blocked pending the owner-run
step. Do not claim approximately 43 resources as a measured inventory. Do not
commit the original source, ciphertext, decrypted views or private resources.
`www/private/employee-portal/` is ignored and outside Astro public output.
The accepted Jotform CSS backup and reconciliation archives are unchanged.
SOPS/age/sops-nix preparation is inactive, with no generated production identity,
recipient, deployed module or server-access activation. Portal browser encryption
remains access friction; internal resources require separate server-enforced
staff/management authorization. See
[consolidated implementation and validation](phase-9-service-portal-consolidated-2026-10-30.md)
and [owner utility instructions](../integrations/employee-portal/README.md).
The actual checkpoint SHA is the commit containing this section; obtain it from
Git history. No push, deployment or cutover is authorized by this work.
## Focused completion, portal styling and Spanish diagnostic — 2026-10-30
Authorized consultation drawers now accept only the documented
`submission-completed` / `formID` envelope from their activated iframe window
at the exact configured Jotform origin while the drawer is open. Object and
bounded JSON-string envelopes are supported; other actions/messages are ignored.
Completion writes the existing global 30-day expiry immediately, reveals EN/ES
acknowledgment, then starts slide-out after five seconds. Manual dismissal or
navigation cancels the countdown. Duplicate completion cannot restart it.
The next deliberate opening replaces the completed iframe; incomplete forms
remain intact across ordinary close/reopen. Load remains fallback-only, never
submission evidence. Real provider-message acceptance requires one owner-run
synthetic submission; automated tests use intercepted local fixtures only.
Portal presentation now restores scoped blue headings, spacing, directories,
orange report buttons and accessible contact accents without retaining arbitrary
classes, styles or scripts. Two synthetic encrypted views are verified. Private
source exposed no plaintext class/CSS semantics, and real view codes were not
available; exact legacy button recognition and visual parity require owner review.
No private content/resource or ciphertext was added to Git or public output.
The reported seven-option Spanish consultation dropdown is an unresolved
Jotform configuration issue: generated EN/ES URLs have identical form ID and
`formContext=consultation`, differing only in `language`. Astro neither supplies
nor edits child dropdown options. Owner should compare the direct hosted Spanish
form and review multilingual option translations/Update Options conditions.
No account changes or real submissions were performed. Seven production and
nine isolated-test placements remain unchanged; production consultation, portal
cutover and site cutover remain unauthorized. See the
[focused correction evidence](phase-9-drawer-portal-corrections-2026-10-30.md).
+1 -278
View File
@@ -1,16 +1,5 @@
# Accessibility Audit
**Checkpoint preparation — 2026-10-15:** The [exact checkpoint manifest](phase-8-checkpoint-manifest-2026-10-15.md)
records final revalidation (156 tests, including Library 53), current publication
metrics, preserved release gates and the source-matching **18:21** offline report.
The [badge correction](phase-8-badge-correction-evidence-2026-10-15.json) supersedes
the earlier white-background derivative and its captures/hash. Current Spanish
artwork preserves original geometry/alpha outside the APROBADO lettering.
Earlier browser failures, capture results and file counts below are dated history;
they are not the latest technical state. Checkpoint preparation is now authorized;
no staging, commit, production activation or human approval has occurred.
## Implemented
- Semantic header, navigation, main, article, section, and footer landmarks.
@@ -18,285 +7,19 @@ no staging, commit, production activation or human approval has occurred.
- Language and direction attributes for English, Spanish, and Arabic.
- Native `details` elements for mobile navigation and FAQ accordions.
- Form labels, autocomplete hints, disabled submission state, and explanatory text.
- Service inquiry drawers use native modal dialogs with focus containment,
Escape, backdrop, and labeled close-button dismissal plus reduced-motion
support.
- Reduced decorative image announcements through empty alt text where appropriate.
- Responsive typography and layouts without fixed text sizing.
- Language-switcher choices are limited to routes that actually exist.
- The language selector uses native `details`/`summary` disclosure semantics and
real links. Visitor navigation is resolved independently from SEO hreflang,
so validated noindex author roots remain reachable without adding them to the
hreflang graph.
- Desktop, mobile, and footer navigation resolve against eligible generated
routes. Cross-language fallbacks are explicitly identified rather than
silently linking visitors to another language.
- Arabic footer phone, email, and Latin-script address values use narrowly
scoped left-to-right bidi isolation while the surrounding footer remains RTL.
- Like buttons expose pressed and disabled state.
- Source-faithful colors, section hierarchy, and controls were retained while
avoiding the source site's modal that obscures content on initial load.
## Manual Review
- Have fluent Spanish/Arabic reviewers assess the newly localized article hero
descriptions and Arabic diagram alternatives in their full article context.
- Review extracted image alt text; source content frequently omitted or duplicated alt text.
- Test keyboard and screen-reader behavior across all migrated pages.
- Perform contrast testing against final approved brand colors.
- Review extracted article heading hierarchy and any table markup.
- Confirm Arabic content and RTL reading order with a fluent reviewer.
- Review Spanish and Arabic operational labels and fallback-language notices
with fluent reviewers. Phase 7 localizes the existing Spanish and Arabic
author-archive labels; fluent review remains pending.
- Test the native language disclosure, mobile navigation, search announcements,
contact links, and full-page RTL reading order with screen readers. Phase
6B.5 validated generated markup and keyboard semantics, but no screen-reader
executable was available in the implementation environment.
- Validate the rebuilt mobile navigation and all full-page responsive
layouts in a browser outside the autonomous sandbox.
## Phase 6C.3 article-image update — 2026-10-12
The current 74-article Library corpus was re-audited after the Phase 6C.2
rewrites. All 74 featured images are informative in their present article
context. The 60 records that still lacked frontmatter descriptions now have
concise, locale-appropriate alt text based on direct visual inspection and the
corresponding public-page evidence. No current featured image is treated as an
accidental empty-alt fallback; this is a decision about the audited corpus, not
a rule that future decorative images must have nonempty alt text.
The three English-text diagrams in the revised Arabic antecedent/consequence
article now use separate self-hosted Arabic SVG counterparts. Each preserves
the source raster and its relationships while replacing the visible labels
with Arabic. The article also retains adjacent Arabic prose and semantic tables
that communicate the same information without relying on the images. The
causal panel order remains left-to-right where reversing it could obscure the
sequence, while Arabic labels render right-to-left within their panels.
At narrow widths, each detailed diagram sits in a keyboard-focusable,
explicitly named horizontal scroll region with a visible focus outline. This
keeps its labels at a readable minimum width without introducing page-level
horizontal overflow.
Generated-markup checks cover featured-image alt propagation to the article,
Open Graph, and Twitter metadata; localized Arabic asset references; and the
absence of the English diagram references from the Arabic body. The SVGs were
rendered locally for visual inspection at their native dimensions. A browser
was not available for desktop/390-pixel overflow checks, and no screen-reader
or fluent-Arabic review was performed. Those checks, plus clinical review of
the translated ABA terminology and diagram relationships, remain required
before cutover.
## Phase 6C.4 article-link update — 2026-10-13
Generated-HTML checks now cover every Library body link's published destination,
asset, and fragment, plus the rendered previous/next/related links. Spanish and
Arabic self-advocacy articles identify their Halloween-guide destination as
English; the two new localized sentences still require fluent-language review.
The play/leisure article retains two native image links to the full-size,
self-hosted infographics. Duplicate expanded images and orphaned lightbox close
symbols were removed. The ABC-data preview links to the existing full-size
worksheet. These static anchors do not require JavaScript; this is markup
verification, not a completed keyboard or no-JavaScript browser session.
Local Chromium failed its sandbox socket check; remote Playwright could not
reach the generated site and subsequently closed its transport. Desktop/mobile
visual checks, focus, image opening and browser Back behavior remain manual
acceptance items. No screen-reader or fluent Arabic/Spanish acceptance is
claimed. The three Phase 6C.3 Arabic diagrams still need visual-language review.
## Phase 6C.5 final verification — 2026-10-13
All 74 featured images retain the individually reviewed alternatives from Phase
6C.3. Final generated-output inspection found and corrected two flattened
screening/evaluation/diagnosis tables (English and Spanish), ten toilet-training
H3 labels that had absorbed adjacent list prose, and the opening headings in the
English/Spanish social-communication articles that had absorbed a quoted
paragraph. Words, article dates and clinical guidance were not changed. The
play/leisure closing CTA is now outside its last FAQ, matching the public page;
all 182 FAQ answers across 30 articles match their visible content and schema.
Actual raster inspection of the three Arabic SVGs found two bounded visual
issues: a replacement-behavior subtitle extended beyond its colored panel, and
a few original English calm-corner title pixels appeared above the overlay.
The subtitle now wraps and the calm-corner overlay starts 10 pixels higher.
Reinspection shows no exposed English labels or clipped Arabic text in the
inspection rasters. The previews used installed DejaVu fonts and losslessly
decoded PNG backing in temporary files because this environment's librsvg did
not render the SVGs' embedded WebP directly. Production SVGs retain their source
WebP artwork. This is raster evidence, not browser/font-fallback acceptance.
All three diagram wrappers retain a named, focusable region, narrow-screen
horizontal scrolling, a 720-pixel minimum image width and focus-outline CSS.
Browser transport remains unavailable; real desktop/390px overflow, keyboard
scrolling, no-JavaScript interactions, screen-reader and fluent Arabic checks
remain **pending**. The source-inherited English tip in the Spanish
positive-reinforcement article also remains a bounded language-review item.
See the final Phase 6C.5 report for the route-specific checklist and release gates.
## Phase 7 shared locale update — 2026-10-14
Spanish Contact and consultation forms now receive the publication locale
explicitly and render Spanish labels, service choices, instructions, submit
text and disabled-submission notices. Contact map landmark/tile alternatives
and zoom titles are localized from server-provided data. Provider/library and
contact values are unchanged. Empty form actions and disabled buttons remain;
these checks do not prove full Enter-key, scripted or no-JavaScript isolation.
Spanish and Arabic author archive eyebrows and list headings are localized.
Arabic BCBA/LBA abbreviations receive LTR isolation without changing identity,
biography or archive SEO. The Spanish reinforcement tip is now fully Spanish,
superseding the minor language finding recorded in Phase 6C.5. New wording is
still pending fluent-language and clinical/editorial acceptance. The Arabic
biography's physician-like wording versus English “clinician” is separately
flagged for organizational and fluent review; it was not silently rewritten.
The recovered Spanish privacy page preserves all ten source sections with
semantic headings, localized metadata and existing contact obfuscation.
Generated HTML tests verify labels, one H1, language, disabled form state and
translation navigation. Playwright opened about:blank, but its transport
closed on the subsequent isolated-local-preview attempt. No site browser,
keyboard, mobile, no-JavaScript or real screen-reader acceptance is claimed.
See [Phase 7 verification plan](phase-7-nonproduction-verification-plan-2026-10-14.md)
for reviewer fields and the API-isolation prerequisite for hosted review.
## Phase 8 bounded verification — 2026-10-14
Generated-HTML smoke checks now cover all 122 eligible routes: zero hard-rule
failures, two source-inherited H1→H3 review warnings (DTT/NET and schedule
consultation). These custom Cheerio rules check basic semantics, labels, alt
presence, fragments, assets and diagram regions; they are not a WCAG audit.
Two authored contrast defects were corrected without changing content or tokens:
inline prose/source-FAQ links now use primary blue and persistent underlines;
navigation/language/byline/diagram focus outlines now use primary blue. On white
and tint backgrounds the foreground contrast is 9.89:1 / 8.89:1, replacing
orange text at 2.23:1 / 2.01:1 and focus outlines at 1.66:1 / 1.49:1. Three focused
regression tests pass. Actual cascade/background/focus-clipping review remains
pending; other colors and controls have not received a complete rendered audit.
Three unchanged Arabic diagrams were rasterized and inspected again: no exposed
English labels or clipped Arabic detected in this DejaVu/librsvg rendering.
This is not browser/font-fallback or fluent-language acceptance. The earlier
statement that wrappers prevent page overflow describes CSS intent; actual
390px containment and keyboard scrolling remain unverified.
Remote browser transport closed before loading the site; only a same-execution
loopback HTTP fetch succeeded. Zero actual browser routes/screenshots, keyboard,
no-JS or real screen-reader sessions are claimed. Contact's external-map failure
fallback and all timed dialogs require actual browser checks. See the
[Phase 8 report](phase-8-visual-accessibility-acceptance-2026-10-14.md) and
[isolated host procedure](phase-8-host-browser-verification-2026-10-14.md).
All stakeholder/Phase 9 gates remain open. Phase 8 is partially verified, not
accepted, and the living handoff has not advanced.
## Phase 8 actual Chromium verification — 2026-10-15
The preceding unavailable-browser status is superseded for the system Chromium
151.0.7922.75 / Playwright 1.61.0 combination. See the
[browser report](phase-8-browser-verification-2026-10-15.md) and
[machine-readable evidence](phase-8-browser-evidence-2026-10-15.json).
All 122 routes loaded; 50 representative routes have full-page 1440/390 captures
and no-JavaScript content observations. The final source received another
122-route desktop check. Forty focused interaction checks pass; one modal focus
boundary remains Review required. No production API attempt was observed;
external map resources were blocked before transmission.
Two further bounded defects were corrected: low-contrast skip/contact/form
notice links now use primary blue and underlines; the homepage director grid
now follows the existing ≤760px single-column rule. Its scoped desktop rule had
caused 382px document width at a 320px viewport. Both homepages now pass actual
320/390/768/1440 reflow checks. Four CSS regression tests pass; full test suites
total 151 passing. These findings do not certify the rest of the palette.
All three unchanged Arabic SVGs rendered with their embedded artwork in Chromium;
inspected desktop captures showed no exposed English labels or clipped Arabic.
Named focusable regions scroll with arrow keys at 390px without page overflow.
Fluent Arabic and clinical review remain mandatory. Chromium AX-tree inspection
confirms Spanish form names/disabled state and Arabic named regions, but also
exposes inherited English “Like this article” and “Similar Blog Posts” labels.
Shared localized labels require a bounded follow-up and fluent review.
The service drawer focuses its heading, closes with Escape and restores prior
focus. Forward Tab reaches the native browser-chrome/BODY boundary before
returning to dialog controls; no background control received focus. Visible
browser/AT review remains pending, not a strict containment pass. A synthetic
fixture's scripted form submission was intercepted, demonstrating that disabled
buttons do not alone isolate submissions. No real form/server POST occurred;
P9-03 still owns the integration/isolation decision.
The two inherited heading skips, actual 200% browser zoom, broader rendered
contrast, complete source-qualified visual comparison, controlled live-map
behavior and real screen-reader acceptance remain open. Computed text resizing
and AX inspection are supplementary evidence, not substitutes. No human
sign-offs were received. All P9 decisions and the living handoff remain unchanged.
## Phase 8 bounded follow-up — 2026-10-15
[Follow-up results](phase-8-browser-verification-2026-10-15.md#bounded-follow-up--2026-10-15)
supersede the specific unresolved technical findings above. Arabic article and
archive counters/footer controls now receive publication locale explicitly;
Arabic names/views/navigation/related labels and isolated counts render correctly.
English/Spanish labels and the entire likes/views API script remain unchanged.
Fluent Arabic review is still pending.
The DTT/NET article's three primary peer sections and consultation's “Start Here”
now use H2 semantics, with identical heading text, IDs, appearance and searchable
text. Inspection established peer-section relationships; a numerical skip alone
was not treated as a WCAG violation. All-route generated audit: 122 pass, zero
hard failures or heading-review warnings.
Read More/eyebrow and selected nav/related-link states now use readable existing
primary colors. Card-author focus outlines also meet light-surface contrast.
Contact/skip links and focus clearance were rechecked. Native dialog Tab and
Shift+Tab, entry, Escape, keyboard Close and return pass at desktop/mobile.
The BODY/documentFocus=false boundary matches a minimal native control, with
background inertness preserved; no custom trap or application change was needed.
Real native tab zoom 200% passes seven high-risk pages: 1440px browser window,
720 CSS-pixel viewport, DPR 2, no page overflow. Overlapping actual viewport
captures replace an unreliable fullPage zoom capture. Both homepages pass
320/390/768/1440 and unchanged Arabic diagrams scroll/render correctly. Thirty
focused browser checks and 154 regression tests pass. This is technical
checkpoint-review readiness, not a complete WCAG audit. Human visual, fluent,
clinical/privacy, real screen-reader and source-fidelity gates remain pending;
all Phase 9 decisions remain unchanged. No production requests or activation.
## Phase 8 consolidated accessibility follow-up — 2026-10-15
See the [complete consolidated report](phase-8-consolidated-followup-2026-10-15.md)
and [evidence](phase-8-consolidated-evidence-2026-10-15.json).
- Phase 7 localization carryover: Spanish homepage now includes the faithful
HSA/FSA translation once after ESA/before Financial Help, with a separate
APROBADO graphic and Spanish alt. English content/artwork unchanged.
- Phase 7 structural carryover: Spanish privacy now has eleven H2 sections;
Información que recopilamos introduces the four existing collection items.
Policy wording/date/contact/metadata unchanged. Historical cache/insecure-TLS
provenance and trusted-source/legal review remain unresolved.
- Phase 8 Tour defect: replace flattened duplicated gallery with one enhanced
nine-slide carousel, caption, wraparound controls, named keyboard-operable
thumbnails, focus, restrained live announcements and full no-JS fallback.
Source is TLS-validated HTTP 200 but October 3 cached/prerendered content,
observed October 15. No live-page scripts executed or fresh-origin claim.
- Preserve prior Arabic UI, headings, contrast, responsive and native-dialog
findings. No changes to likes/views script, forms, publication architecture,
dependencies, hosting, SESSION_HANDOFF or pending Phase 9 decisions.
- Pass: 156 regression tests; 21 targeted Chromium checks and two actual-style/
reduced-motion probes; 122 generated-route static checks; link/image/blog
audits and both builds. Native 200% zoom on Tour/privacy adds 26 overlapping
frames, alongside 20 full-page captures and four crops (all outside Git).
- Counts unchanged: 122 routes/canonicals, 108 sitemap, 180 hreflang/55 routes,
25 sets, 74 Library records, 55/12/7 search, nine archives/redirects,
182 Library FAQ answers on 30 articles. Final staging 122 noindex,nofollow,
empty sitemap, zero hreflang. Raw all-site FAQ population is separately 254/32.
- Final explicit source-matching offline artifact:
[17-41-40-404Z](route-reconciliation-2026-10-15-offline-17-41-40-404Z.json),
133 dispositions/70 reused requests. Read-only consistency check passed.
**PHASE 8 TECHNICALLY READY FOR CHECKPOINT REVIEW**, not accepted by stakeholders.
Fluent Spanish/Arabic, HSA financial claims, clinical/organizational review,
privacy/legal/trusted-source comparison, real screen reader, native-dialog AT,
Arabic diagrams, source-design and non-Chromium acceptance remain open.
P9-01 through P9-10 all Pending decision; Phase 10 cutover remains unauthorized.
No staging, commit, checkpoint preparation, deployment or integration activation.
+3 -3
View File
@@ -1,7 +1,7 @@
# Blog Content Audit
Checked 74 blog post bodies for layout content duplicated in Markdown.
Verified 182 FAQ questions across 30 FAQ-bearing posts.
Detected 58 source-faithful blog blockquotes.
Checked 65 blog post bodies for layout content duplicated in Markdown.
Verified 125 FAQ questions across 19 FAQ-bearing posts.
Detected 32 source-faithful blog blockquotes.
No duplicated article headers or invalid MDX FAQ components were detected.
+9 -14
View File
@@ -1,14 +1,14 @@
# Cleanup Log
- Replaced HubSpot-generated wrappers, inline styles, scripts, analytics, and modules with reusable Astro components.
- Preserved canonical clean URLs while excluding HubSpot query-string and AMP duplicates.
- Preserved canonical clean URLs while excluding local mirror query-string and AMP duplicates.
- Consolidated responsive `hs-fs` image variants to canonical `hubfs` assets where available.
- Excluded HubSpot CSS and JavaScript from the new public asset package.
- Self-hosted canonical images, SVGs, fonts, and PDFs where practical.
- Excluded mirrored HubSpot CSS and JavaScript from the new public asset package.
- Self-hosted canonical images, SVGs, fonts, and PDFs from the mirror.
- Recreated navigation and footer from structured JSON.
- Recreated visible contact and consultation forms as static accessible HTML.
- Used the source palette: AIA blue `#254080`, dark blue, straw yellow, orange, and teal.
- Used self-hosted Playfair Display headings, Rubik body copy, and Caveat accent font.
- Used the live site's locally mirrored Playfair Display headings, Rubik body copy, and Caveat accent font.
- Added multilingual collection and route structure with Arabic RTL support.
- Kept all extracted source content editable as Markdown.
- Replaced the initial generic rounded-card visual system with live-derived
@@ -21,26 +21,21 @@
- Reorganized the homepage source into named `home:` frontmatter blocks so the
content is easier to inspect and edit without changing the rendered layout.
- Replaced the extracted linear team article with a dedicated live-derived team grid.
- Repaired rewritten PDF, lightbox, CTA, and relative content links.
- 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 HubSpot injected through malformed
inline `background-image` styles.
- 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.
- Removed duplicated article titles, author/date blocks, and featured images
from all 65 blog Markdown bodies; these elements are rendered by the shared
blog-post layout. Added a blog-content audit to prevent recurrence.
blog-post layout. Updated both extractors and added a blog-content audit to
prevent recurrence.
- Converted 19 FAQ-bearing blog posts to MDX and restored a reusable
`FAQAccordion.astro` component that owns the live-style accordion and
matching `FAQPage` JSON-LD.
- Converted the insurance content entry to MDX so its prose, carrier data, and
FAQ data have one editable source; reduced `InsurancePage.astro` to a
presentation-only wrapper that renders the content slot.
- Reconstructed the giveback page's four live-derived content bands and
restored its Amazon wishlist and GivingFountain actions without carrying
over HubSpot layout wrappers.
- Restored 32 blockquotes across 15 English and Spanish blog posts, including
source emphasis, links, and the self-hosted quote-mark decoration; fixed
fallback extraction to preserve them.
@@ -1,178 +0,0 @@
# AIA employee portal — migration brief and decision record
**Recorded:** 2026-10-08
**Project:** HubSpot to Astro migration, branch `faithful-astro-migration`
**Status:** Requirements clarified; implementation architecture and launch authorization still pending
**Related milestone:** Phase 9 human-decision gate, with implementation and verification required before cutover
## Purpose
Preserve the existing staff-facing `/employee-portal` experience during the move
from HubSpot to Astro on the AIA Contabo VPS. This is a small internal resource,
**not** an ordinary public marketing page. The owner describes its intended
protection as low-security, but that description is not a determination that the
underlying staff data or linked forms are safe to publish.
The current user-supplied requirements supersede earlier audit uncertainty
about the purpose of this route. They do **not** authorize a new authentication
implementation or relaxation of security/privacy checks.
## Confirmed legacy behavior (owner-supplied)
- The HubSpot employee portal contains **staff contact information** and links
or access to **day-to-day clinical-operations forms**.
- It has **two shared-password access levels**: general staff and management.
Preserve the separation and the intended content available to each group.
- The password handling and content are supplied in JavaScript/HTML through
the HubSpot page's **footer HTML field**.
- The supplied script embeds two independent encrypted HTML streams in a JSON
script element. The implementation labels them
`AES-256-CBC+HMAC-SHA256`, with PBKDF2-HMAC-SHA256 (200,000 iterations) used to
derive separate encryption and MAC keys from the entered passphrase.
- On password submission, the browser tries each stream; a matching MAC is
checked before decryption. On success, the script replaces the password
form with the decrypted HTML. Incorrect passwords leave the form visible.
- Decryption happens **entirely in the browser**, without an authenticated
server-side session. The encrypted data is downloadable with the page and
can be subjected to **offline password guesses**.
The supplied excerpt shows the encryption/decryption logic and encrypted
payload, but not the decrypted staff/management HTML or every surrounding
page element. The inventory of individual contacts, form destinations,
permissions, and client-side behavior therefore still requires a separate
owner-approved inspection.
**Sensitive material deliberately omitted:** the actual passphrases, encrypted
payload, decrypted HTML, contacts, staff details, and form-specific data are
not included in this document or any proposed Git commit. Do not paste,
log, or commit them. Rotate the shared passphrases before any migration
cutover; supply replacement secrets through an approved private mechanism.
## Current Astro state (repository-verified 2026-10-08)
- `www/src/content/pages/en/employee-portal.md` defines the
`/employee-portal` page route with metadata only; it has no portal body.
- It is `draft: false` and `noindex: true`.
- Phase 3A deliberately preserves the accessible local route while excluding
it from the production-policy sitemap. The staging build remains globally
`noindex,nofollow`.
- The existing migration audit listed employee portal replacement/access as
a human-decision gate. This brief clarifies the requirements without
treating the empty Astro route as a completed migration.
References:
- `www/reports/migration-audit-2026-10-06.md`
- `www/reports/migration-summary.md`
- `www/reports/migration-conversation-2026-10-07.txt`
- `www/src/content/pages/en/employee-portal.md`
## Desired migration behavior
1. Preserve the public-facing **route** `/employee-portal`, but do not expose
internal content to unauthenticated visitors.
2. Preserve **general staff** and **management** content separation.
3. Preserve the practical staff workflow: contact lookup, form links, and
day-to-day usability, including mobile layout.
4. Maintain the established `noindex` and sitemap-exclusion policy. Do not
add a translation alternate for this noindex route.
5. Audit each form link, embedded form, external provider, and asset before
migration. Identify whether any workflow collects, displays, or transmits
patient data or other sensitive information. Do not assume an internal
form's data handling is safe merely because the portal is gated.
6. Do not enable third-party advertising or general-purpose analytics tags
within the protected portal without an approved privacy review.
7. Preserve existing functionality without prematurely creating a user-account
database, integrating a full identity provider, or changing clinical forms.
Any such change requires a separate owner decision.
## Authentication/hosting decision — NOT YET RESOLVED
Two approaches are plausible. Do not select one implicitly.
**A. Reproduce the existing browser-side encrypted-content model.**
This offers closer functional compatibility and may remain entirely static,
but it is **obfuscation/access friction rather than robust access control**:
all ciphertext is publicly downloadable and shared passphrases can be tested
offline. It offers no individual account revocation or reliable per-user audit
trail. Use only after explicit owner acceptance of these limitations and
review of all included content.
**B. Protect staff and management resources at the Contabo server/edge.**
For example, separate protected URL/resource areas with nginx or another
server-side access control, while keeping `/employee-portal` as the entry
point. This avoids distributing readable internal content as public HTML and
can separate the two groups, but requires a design for two access levels,
credential distribution/revocation, and hosting operations. A single
undifferentiated HTTP Basic Auth gate is **not by itself** sufficient to enforce
different staff and management permissions.
**Security boundary:** `noindex` and omission from the sitemap are SEO
directives, **not** access controls. If server-side protection is selected,
protected plaintext must not be shipped as publicly retrievable assets in the
Astro `dist/` tree, public Git repository, or an unguarded CDN. Do not embed
passwords in browser JavaScript, frontmatter, static environment variables, or
committed web-server config.
## Decisions to obtain before implementation
- Confirm the exact resources visible to **staff** versus **management**
without storing them in public migration documentation.
- Classify staff contact details, form links, linked systems, and any clinical
or patient-related content; decide what is allowed in an externally reachable
portal.
- Select browser-side compatibility or server-side Contabo protection (and
whether existing URL/layout behavior should be retained verbatim).
- Decide how replacement credentials will be generated, distributed, rotated,
and revoked. Avoid reusing the old shared passphrases.
- Approve which portal forms/links are maintained, replaced, removed, or
re-hosted. Check destination URLs and privacy implications.
- Name the approver for both access-level mapping and launch acceptance.
## Future implementation milestone (separate from Phase 3B)
1. Perform a **read-only inventory** of the existing decrypted staff and
management views through owner-authorized access; record only non-sensitive
structure, required features, and form destinations in public reports.
2. Obtain the decisions above. Produce a short design and threat/operational
tradeoff review before implementing anything.
3. Implement in a scoped, reviewable milestone. Preserve the route and
publication policy; do not alter other migration page families.
4. Validate the access boundary: unauthenticated users cannot read protected
content; staff cannot read management-only content; management can access
its intended resources. Check direct URLs, page assets, and caching.
5. Validate UI and operations: wrong credentials, successful access, refresh,
mobile layout, keyboard access, link destinations, and form workflows.
6. Check `noindex`, sitemap omission, no hreflang, and absence of unintended
tracking/PHI leakage. Conduct an authorized privacy/security review.
7. Keep rollback instructions and credential-rotation procedures alongside
the Contabo cutover checklist. Do not activate until separately approved.
## Scope note
This is **documentation only**. It must not change Phase 3A publication policy,
Phase 3B hreflang implementation, Astro routing, production access, forms,
analytics, or server configuration. It does not claim authentication,
HIPAA compliance, or release readiness.
## 2026-10-30 owner authorization and implementation addendum
The owner explicitly authorized the two-stream browser-encrypted compatibility
model for development, superseding the earlier implementation hold for that
bounded scope. Production authorization and server-side resource protection are
still unresolved. The new scoped EmployeePortal component preserves the existing
route/SEO policy, local password entry, HMAC verification before decryption,
locked/unavailable default and passive content rendering.
The read-only source is at
`/home/alice/projects/wrk/aia/local-archives/aia-employee-portal-hubspot-footer-source.txt`.
Its two-stream structure and algorithm were inspected without exposing ciphertext
or plaintext. Legitimate codes were not available to the agent. Real-view
fidelity and exact resource counts remain blocked, not accepted. No real document
was fetched or published. The owner-run migration utility performs private
collection and approved link rewriting/re-encryption; see
[private workflow instructions](../integrations/employee-portal/README.md).
SOPS/age/sops-nix templates are prepared but inactive. Encryption of deployment
secrets does not authorize public delivery of staff/management documents. The
[consolidated report](phase-9-service-portal-consolidated-2026-10-30.md) records
synthetic tests and the separate remaining owner/cutover gates.
@@ -1,156 +0,0 @@
# Google Ads consultation-form conversion: Astro implementation handoff
**Recorded:** 2026-10-08
**Repository branch:** `faithful-astro-migration`
**Status:** **Configuration documented only. NOT approved for production installation or activation.**
This document preserves the conversion action configured in the AIA Google Ads
organization account for the future Astro consultation/ABA-therapy landing pages.
It is a handoff to the site-migration and landing-page implementation work, **not**
authorization to install advertising tags. Follow the repository's
`AGENTS.md`/form-implementation constraints. As of this document, existing
migration forms are intentionally static; do not silently wire them to a backend
or add tracking while working on the visual migration.
## Google Ads configuration (verified in account UI)
| Field | Value |
| --- | --- |
| Google Ads customer/account | `515-940-4739` |
| Conversion action | `AIA | Consultation Form Submitted` |
| Goal/category | `Submit lead form` |
| Source | Website, **manual event** |
| Optimization | Primary; account-default goal (alongside Phone call lead) |
| Value | USD $1, fixed nominal reporting value (not actual revenue) |
| Count | One conversion per ad interaction |
| Click-through conversion window | 90 days |
| Engaged-view / view-through windows | 3 days / 1 day |
| Attribution | Data-driven |
| Enhanced conversions | **Not configured; do not enable** |
| Google tag setup | Not installed/verified for this new account |
| Conversion type ID (Google Ads UI reference only) | `7830657062` |
**Identifiers copied from the Google Ads “See event snippet” dialog:**
- **Google Ads destination / tag ID:** `AW-18494479353`
- **Conversion label:** `MzxbCKaw-ZUdEPm37fJE`
- **`send_to` value:** `AW-18494479353/MzxbCKaw-ZUdEPm37fJE`
The event snippet displayed in Google Ads is:
```html
<!-- REFERENCE ONLY. DO NOT DEPLOY WITHOUT PRIVACY APPROVAL. -->
<script>
gtag('event', 'conversion', {
'send_to': 'AW-18494479353/MzxbCKaw-ZUdEPm37fJE'
});
</script>
```
The `AW-` destination ID and conversion label are **not secrets**. Their
publication in source documentation does not imply permission to transmit data
to Google.
## Intended conversion semantics
One conversion represents **one consultation/ABA-therapy inquiry whose form
submission is accepted successfully by the approved API**, not a page visit,
form start, validation attempt, button click, or failed request.
The Google Ads dialog offered `Page load` and `Click` snippet options. The
`Page load` option was used to **retrieve the event syntax**, not as a mandate
to fire on arbitrary page loads. For the Astro/API flow, **prefer triggering
explicitly after the API returns a verified success response**, provided the
privacy review has approved the entire data flow.
Avoid a generic `/thank-you` page-load conversion: direct visits, refreshes,
or failed/subsequently redirected submissions can create false conversions
unless access and deduplication are robustly controlled. If confirmation-page
measurement is selected later, document and test how successful submissions
are authenticated and repeated visits are prevented from counting again.
## Integration requirements — gated, not yet authorized
1. **Privacy/HIPAA and Google Ads policy approval comes first.** Review with
AIA's responsible privacy/compliance team whether any Google tag may load
on the relevant pages, including the confirmation page. A health-service URL
and request metadata can disclose sensitive context even when no form fields
are sent. Review URL/path/query string, referrer, IP/device information,
cookies, network requests, automatic collection, consent, and applicable
Google terms/policies. **No tag loading at all** until that review is
completed and explicitly approved; a nominally sanitized `gtag` event is
not itself evidence of HIPAA compliance.
2. **Keep enhanced conversions and customer-data features off.** Do not send
names, emails, phone numbers, diagnoses, dates of birth, form contents,
hashed identifiers, `user_data`, or any patient-related values to Google.
Do not import sensitive customer lists or enable remarketing/health-audience
personalization. Don't append PII/PHI to redirect URLs, analytics events,
or advertising parameters.
3. **Do not add the base Google tag globally** to `src/layouts` or shared
head scripts as part of the ordinary site migration. If approved, provide
the minimum audited, route-specific implementation with explicit policy
controls. The Google Ads event requires a correctly initialized Google tag
(or a separately approved GTM implementation); the event snippet alone
cannot measure a conversion.
4. **Fire only after confirmed API success.** Use the real form endpoint's
documented response contract, not a presumed HTTP 200 or a click handler.
Fail closed on network error, invalid/partial responses, validation failure,
or spam rejection. Guard against duplicate calls from double-clicks,
retries, navigation, and refreshes.
5. **Keep the event minimal.** Once explicitly approved and initialized, the
only required conversion-event field in the recorded snippet is `send_to`.
Do not add `value`, `currency`, `transaction_id`, URL parameters, or
custom data without separate measurement/privacy review.
6. **Test safely.** First unit/integration-test form-success logic using a
mocked `gtag` and synthetic submissions. Test zero events on errors and
exactly one on verified success; inspect final URLs and outgoing requests.
Any real Google-network testing is itself tag deployment and requires the
same privacy approval. Verify the event in Google Ads/Tag diagnostics after
approval and deployment.
7. **Release gate.** Do not enable the paused campaign until the landing pages
are production-ready, successful forms are verified end to end, conversion
measurement is tested and approved, the healthcare/call-asset terms issue is
resolved, and the advertising-policy review is complete.
### Illustrative invocation — not production-ready code
```ts
// Documentation-only. Run ONLY inside a privacy-approved implementation,
// after the approved API's actual success condition has been verified and
// the approved Google tag is initialized. Add submission-level deduplication.
gtag('event', 'conversion', {
send_to: 'AW-18494479353/MzxbCKaw-ZUdEPm37fJE',
});
```
Do **not** paste that example into a generic `submit` event handler or a
shared page layout: doing so before the asynchronous API response succeeds
would count attempted or failed inquiries.
## Related campaign and implementation notes
- The Search campaign in Google Ads account `515-940-4739` is intended to
remain **paused** during the Astro/Contabo migration and privacy audit.
- The other account-default Primary goal is `Phone call lead`, presently an
`AI-qualified call leads` action with a 60-second qualifying duration and
`Count = One`. Its Call and Messaging Ads Terms/HIPAA-exclusion question
is a separate launch blocker.
- The standalone advertising landing pages and associated form API work may
have their own repository or implementation handoff. Reconcile this document
with that source before making changes; do not assume the migration repo's
static forms already implement those endpoints.
- For privacy, keep identifiers limited to the public Ads destination ID and
conversion label; **no API credentials, patient examples, or submitted lead
data belong in this documentation**.
## Implementation checklist
- [x] Create the Google Ads manual Website conversion action and record IDs.
- [x] Configure Primary, One, $1, data-driven attribution; enhanced conversions off.
- [ ] Approve the exact third-party tag/data-flow design through AIA privacy review.
- [ ] Confirm form API success contract and documented submission deduplication.
- [ ] Implement a strictly gated, audited event only on verified form success.
- [ ] Verify outgoing network payloads and URLs contain no sensitive information.
- [ ] Complete approved end-to-end tracking tests and inspect Google Ads diagnostics.
- [ ] Confirm Google call-assets terms/HIPAA exclusion and other launch gates.
- [ ] Unpause campaign only after written go-live approval.
-326
View File
@@ -1,326 +0,0 @@
# Migration audit — accepted baseline and Phase 1 evidence
Report date: **2026-10-06**, as requested. Application baseline: commit
`147b55c586f1a176050551003af98903901833eb` on `faithful-astro-migration`.
## Evidence dates and interpretation
- **Inherited accepted findings:** the audit accepted in the migration planning
conversation. Its observations span October 5–6, 2026. The temporary JSON/HTML
did not retain exact request timestamps; these remain `null` in the durable
baseline. File modification times were not substituted for observation times.
- **Fresh verified observations:** the shell's UTC clock recorded production
requests on **2026-10-07, 00:56:33–00:57:25 UTC**. This differs from the report's
requested date and is intentionally not backdated.
- **Inferences and uncertainty:** route presence does not establish content,
visual, accessibility, or functional equivalence. Unrequested routes remain
HTTP-unverified. Sitemap `lastmod` is a discovery hint, not a verified edit date.
Durable evidence:
- [Accepted route baseline](route-baseline-2026-10-06.json): compact extraction of
the saved inventories and selected HTML metadata/link references; no HTML,
article bodies, form payloads, or scripts are committed.
- [Current route reconciliation](route-reconciliation-2026-10-07-offline.json):
fresh production observations reconciled with generated/local routes. Its
final derivation was validated offline; the original production request times
and complete request ledger are retained. `mode: offline-reconciliation` does
not mean the production observations were invented or newly requested offline.
- [Historical migration summary](migration-summary.md): preserved unchanged;
its earlier completion claims are not current acceptance evidence.
The `/tmp` paths recorded in baseline provenance are historical origins only.
The tool and offline checks do not depend on those files still existing.
## Executive summary
**Inherited finding:** this is a substantial, buildable full-site migration,
not a new scaffold. Most page families exist, but route coverage overstates
readiness. Rendering, factual content, conversion behavior, and SEO need work.
**Fresh route verification:** the core inventory is unchanged: 97 generated
HTML pages, 102 production sitemap URLs, and 92 overlapping routes. Ten
sitemap-listed pages are missing locally. Five generated routes are absent
from the production sitemap; four remain live and one is the `/ar` placeholder.
Phase 1 adds evidence and tooling only. It does not repair rendering, alter
content, activate forms, change indexing, or implement redirects.
## Last known project state
**Inherited, corroborated by unchanged HEAD:** initial migration work landed in
June 2026. The newest local English article publication date was June 1, 2026.
Subsequent work concentrated on fidelity, page-specific layouts, FAQ behavior,
static inquiry drawers, and authoring infrastructure. Astro upgrades occurred
in July. The final August 28 commits enabled Sätteri features, restored Giveback
layout, and included MDX routes in sitemap generation.
Phase 0 fetched both remotes successfully. The migration branch was ahead of
`origin/faithful-astro-migration` by 14 commits and its `github` counterpart by
16; no remote-only commits were found. Local `main` and the reference foundation
branch matched their corresponding remote branches. The pre-existing untracked
`merge-plan.md` remains separate, unapproved merger planning, not migration
implementation authority.
## Current architecture
**Inherited inspection:** Astro 7.1.5, TypeScript, npm, static output, Zod content
collections, Markdown/MDX, plain CSS, and self-hosted fonts remain a suitable
foundation. English/Spanish/Arabic routing and RTL support exist. Some page copy
is rendered from dedicated components rather than its Markdown record.
The source contains 21 English, nine Spanish, and two Arabic page records;
46 English, 12 Spanish, and seven Arabic posts; and one author record per
language. Assets comprise 172 image files, 20 font files, and two PDFs.
**Inherited blocker, deliberately unchanged:** directive parsing removes the
`:1` and `:2` portions of ordinary therapy ratios. The accepted audit reproduced
this despite a passing build. Phase 2 must inspect intentional directive use
before changing the parser and preserve explicit heading IDs.
## Migration coverage
| Area | Accepted assessment | Remaining work |
| --- | --- | --- |
| Service/conversion pages | Implemented, materially stale in places | Ages, eligibility, program naming, CTA destinations, consultation/referral copy |
| Homepages | Substantial implementation | English HSA/FSA section and metadata; source-specific Spanish reconciliation |
| About, careers, intake, insurance | Sampled substantive copy appeared aligned | Full visual/functional acceptance remains incomplete |
| Team | Implemented but stale | Reconcile names, roles, ordering, images |
| Employee portal | Effectively an empty page body | Human decision on replacement/access behavior |
| Library | 65 local posts; partial index behavior | Nine missing English posts, rewritten articles, search, pagination, authors |
| Spanish | Partial page coverage; 12 Library routes | Privacy page, updated source-supported translations, human language review |
| Arabic | Seven Library posts plus index and homepage placeholder | RTL/content review; intended unpublished homepage policy not implemented |
| SEO | Shared metadata, organization schema, selected FAQs | Publication rules, canonicals, hreflang, article/FAQ schema, social gaps |
| Forms/integrations | Static forms; selected external dependencies | Explicit activation and ownership decisions before launch |
These are inherited content assessments. Phase 1's fresh requests recheck route
and selected metadata evidence, not every paragraph or page layout.
## Route reconciliation
| Measure | Accepted core count | Fresh result |
| --- | ---: | ---: |
| Generated HTML pages | 97 | 97 |
| Production sitemap URLs | 102 | 102 |
| Sitemap/local overlap | 92 | 92 |
| Sitemap URLs missing locally | 10 | 10 |
| Local generated routes absent from sitemap | 5 | 5 |
| Production sitemap additions/removals | — | 0 / 0 |
The final machine inventory has **129 normalized route keys**, including
aliases, utility/archive routes, and the local placeholder. This is not 129
verified production pages. `robots.txt` and `sitemap.xml` are recorded separately
as two generated utilities, not counted among the 97 HTML pages.
Ten sitemap-listed missing routes, all freshly verified HTTP 200:
```text
/es/privacy-policy
/library/does-aba-therapy-replace-school
/library/autism-daily-living-skills-challenges
/library/how-many-hours-aba-child-need
/library/autism-after-school-meltdowns
/library/autism-back-to-school-transition
/library/autism-social-skills-by-age
/library/sleep-issues-autistic-children
/library/halloween-and-autism
/library/picky-eating-autism-parent-guide
```
Fresh checks preserve these sitemap-absent local routes as live:
- `/employee-portal`: HTTP 200.
- `/schedule-consultation`: HTTP 200, source `noindex`.
- `/library/community-highlight-meet-rula-diab`: HTTP 200, external canonical.
- `/library/new-aia-scottsdale-office`: HTTP 200, external canonical.
`/ar` remains HTTP 404 in production. Locally it is **generated, `draft:false`,
and identifiable as placeholder content**. Its intended nonpublication is an
accepted future policy, not current implemented behavior.
All three short aliases remain 301 redirects to their hyphenated service URLs:
`/aba`, `/autismevaluations`, and `/learnersocialclub`.
### Additional discoveries and checking-method differences
- Six author-pagination links were recovered from archived HTML beyond the
earlier narrative: English `/library/author/rula-diab/page/2` through `/6`, and
Spanish `/es/library/author/rula-diab/page/2`. They are historical discoveries,
not evidence of six new publications. All now return 200 in fresh checks.
- English Library pagination pages 3–6, previously only discovered, now return
200. Search, the campaign page, three author indexes, and both languages'
page-2 listings also remain verified live.
- Two links were first inventoried in the fresh pass:
`/library/page/1` and `/library/author/rula-diab/page/1`. They were discovered
during the final bounded pagination pass and were **not requested**. Do not
assume either is absent, a 200, or a redirect.
- `/es` returns 301 to `/es/` without redirect following. The original audit
followed redirects and recorded the final 200. This is a transport observation
difference, **not established evidence that production changed**. The tool
records the Location and does not compare unavailable redirect-body metadata
as if title/canonical fields had been deleted.
There are 21 verified HTTP-200 routes outside the sitemap, including the four
already represented locally. The route report distinguishes these from 59
overlapping sitemap-listed routes not individually HTTP-verified in this pass.
## Significant content changes preserved from the accepted audit
These findings remain historical evidence pending page-specific reconciliation:
1. [ABA](https://www.azinstitute4autism.com/aba-therapy) and
[referrals](https://www.azinstitute4autism.com/referrals) differed from local
ages/eligibility copy; the individual ABA program described 18 months–8 years.
2. English/Spanish [school readiness](https://www.azinstitute4autism.com/library/aba-school-readiness-arizona)
changed from academy promotion to a broader guide; the fall-break article
also changed materially.
3. The [English homepage](https://www.azinstitute4autism.com/) added HSA/FSA
information absent locally. That does not itself justify new JSON-LD.
4. The [team listing](https://www.azinstitute4autism.com/team) differed from
local names; website differences do not prove employment status.
5. Spanish privacy content and nine English articles were absent locally.
6. `/lp/early-intervention` existed with an API-backed form; its ownership remains
a separate decision from full-site migration.
## SEO / URL risks
**Inherited findings, not repaired:** syndicated articles self-canonicalize
locally despite external production canonicals; hreflang is absent; BlogPosting
and standalone FAQPage schema are missing; display H1 is conflated with SEO
title; publication exceptions are not modeled; and the separate sitemap
generator extracts canonical strings without adequate publication exclusions.
Global staging noindex currently protects all generated pages. Turning indexing
on would not implement the intended `/ar` or `/schedule-consultation` exceptions.
Archive/search routes lack implementations or explicit redirect dispositions.
Existing nginx rewrites are report artifacts, not deployed routing behavior.
The route audit does not enforce these future policies or label overlaps as
content-aligned. It records observed behavior for subsequent milestones.
## Forms / analytics / external integrations
**Inherited findings:** production uses Jotform, HubSpot forms, a campaign API,
Google Analytics/consent setup, and Ahrefs analytics. Astro has disabled static
forms, configurable counters, payment links, video, and Leaflet/OpenStreetMap.
Form and tracking parity is incomplete. No legal compliance conclusion is made.
Phase 1 used raw GET requests only. It did not execute production JavaScript,
submit forms, contact form/counter APIs, unlock the portal, or fetch external
canonical publishers. Same-origin GET form actions were recorded as discovery
references (for example `/search`); no field values were submitted.
## Technical debt, sequence, and human gates
Keep the existing foundation. Resume through individually reviewed milestones:
Markdown rendering; route/publication policy; genuine translation relationships;
display/social/article/FAQ metadata; high-impact service and homepage facts;
Library capability design and content batches; source-supported multilingual
work; detailed visual/accessibility QA; and eventual cutover preparation.
Library search, pagination, and author routes are required capabilities. Inspect
the Astro architecture before selecting search technology; do not copy HubSpot
implementation details by default. Correct material service facts before
extensive pixel-level matching. Substantive translation changes finish ready
for human language review, not self-approved fluency.
Human decisions remain required for employee access, campaign ownership,
production form activation, analytics/consent architecture, and conflicting
public eligibility claims. None is authorized as implementation by this report.
## Reproducing the route reconciliation
Run from `www/`, using the already installed project dependencies:
```sh
npm run build
npm run test:routes
npm run audit:routes
npm run audit:routes -- --check
```
- `audit:routes` requires existing build output. It reads source page/post
records and generated HTML; discovers through robots.txt, sitemap(s), five
locale/index seeds, links, and targeted checks; then writes a new dated JSON.
- It uses sequential same-origin GET requests, at least 750 ms between starts
(or the applicable robots crawl-delay), 15-second timeouts, ten sitemap and
80-request limits. It records redirects without following them and stops
network work on 429, 5xx, or a network failure. Incomplete discovery exits
nonzero with evidence where available; inability to establish robots policy
stops before page discovery.
- Known tracking parameters and trailing slashes are normalized. Unknown and
semantic query parameters, their ordering, and fragments are preserved.
Fragment references share one HTTP route and are not fetched separately.
Arbitrary query variants are not automatically crawled.
- Only 404/410 establish verified absence. Sitemap omission, redirects, blocked
requests, and network failures never do. Locale and canonical come from HTML
where actually inspected; unrequested metadata is not invented.
- Normalized route rows retain local counterparts, discovery sources/times,
request statuses/times, metadata where collected, and a route-level
disposition. The request ledger separately dates each discovery document.
- Subsequent runs create new files; they do not overwrite the accepted baseline
or prior snapshots. Baseline hashes protect the inherited evidence identity.
Offline validation of this exact snapshot, with no network or writes:
```sh
npm run audit:routes -- --check --evidence reports/route-reconciliation-2026-10-07-offline.json
```
After intentional local changes, rebuild and reconcile against the same saved
production evidence without making production requests:
```sh
npm run build
npm run audit:routes -- --offline --evidence reports/route-reconciliation-2026-10-07-offline.json
npm run audit:routes -- --check
```
`--check` defaults to the snapshot with the latest `generatedAt`. It verifies
the application source/asset fingerprint and recomputes route rows, totals, and
baseline comparisons. It fails on mismatches or saved discovery warnings. It
does **not** certify that production has remained unchanged since observation.
Build before capture when application files changed: the tool requires `dist`
but cannot prove that an arbitrary pre-existing build was produced from the
current source. Application fingerprints exclude this audit tooling and reports.
## Phase 1 validation and remaining uncertainty
- Focused offline tests cover normalization, meaningful queries/fragments,
deduplication, classification, placeholders, redirects, external canonicals,
inherited comparisons, and robots handling.
- Fresh discovery performed 70 requests: one robots, one sitemap, 68 pages.
Responses: 65 HTTP 200, four 301, one 404. No failures or discovery warnings.
One additional preflight `robots.txt` GET preceded the tool run and is not
counted in its request ledger; no other production requests were made in Phase 1.
- The sitemap membership and ten missing content routes match the accepted
baseline. Known gaps remain findings; they do not make a consistent inventory
fail its offline check.
- Per-page content/layout parity, full accessibility testing, linguistic review,
external integrations, and the two newly discovered `/page/1` behaviors remain
outside this milestone's verification.
- `npm run test:routes`: **9/9 passed**, entirely offline.
- `npm run audit:routes`: **passed**, with the fresh observations above.
- `npm run audit:routes -- --offline --evidence ...`: **passed**, retaining the
same production observations while validating final comparison logic. The
superseded preliminary generated artifact was not retained in the repository.
- `npm run audit:routes -- --check`: **passed** against the final saved snapshot,
including after the final build; no network requests or file writes.
- `npm run build`: **passed**, 97 pages, zero errors/warnings/hints.
- `npm run audit:links`: **passed**, zero broken internal links; the existing
broken-links report remained byte-for-byte unchanged.
- `git diff --check`: **passed**. Application source, assets, Astro configuration,
dependency declarations, lockfile, and existing migration reports are unchanged.
The package manifest adds only the two audit/test commands.
- All 97 generated pages retain the saved baseline titles, descriptions,
canonicals, headings, JSON-LD, and main-content text after normalizing existing
randomly generated contact-obfuscation IDs. Whole-output hashes differ because
`ContactObfuscation.astro` already uses `Math.random()` for those IDs; byte
identity is not claimed. No application behavior change was introduced.
- `merge-plan.md` remains untracked and unchanged. Before/after SHA-256:
`015db80cdbaf7d68799265d2070db760155c342b432ce6795f17ebc2218c641c`.
**Recommendation:** Phase 2 is the next useful milestone, subject to approval.
The ratio defect remains unchanged. Search the complete Markdown/MDX corpus and
directive consumers before altering parsing; retain explicit heading IDs and
add rendered Markdown/MDX regression coverage. No Phase 2 work was performed.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-74
View File
@@ -1,77 +1,3 @@
## Include these directives inside the public HTTPS server block, before the
## generic static `location /` handler. Root (`/`) is the only trailing-slash
## public URL; every other terminal slash receives a query-preserving 308.
location ~ ^(.+?)/+$ {
return 308 $1$is_args$args;
}
## The static handler must serve the generated directory artifact at its
## slashless public path. Do not use `$uri/`, which permits nginx's automatic
## directory-slash redirect before `$uri/index.html` can be served.
location / {
try_files $uri $uri/index.html $uri.html =404;
}
## HubSpot redirect export imported from repository-root `url-redirects.csv`
## on 2026-11-01. The export contains 45 STANDARD 301 rules. The three aliases
## already generated below (`/aba`, `/autismevaluations`, and
## `/learnersocialclub`) are intentionally not duplicated here.
##
## The IndexNow verification-file redirect retains HubSpot's original external
## target. Before cutover, confirm that target remains reachable after this
## hostname points at nginx; serving the required verification file locally may
## be necessary instead.
rewrite ^/abaportal$ /employee-portal permanent;
rewrite ^/aiaportal$ /employee-portal permanent;
rewrite ^/giveback$ /donate-autism-giveback permanent;
rewrite ^/blog$ /library permanent;
rewrite ^/donate$ /donate-autism-giveback permanent;
rewrite ^/contactus$ /contact permanent;
rewrite ^/post/4waysonhowtoreducebehaviormanagement$ /library/reduce-behavior-management permanent;
rewrite ^/post/playandleisureskillsforchildrenwithautism$ /library/play-leisure-skills permanent;
rewrite ^/post/managing-aggressive-behavior-outbursts-and-proper-communication-with-your-child-during-those-moments$ /library/managing-aggressive-behavior-outbursts permanent;
rewrite ^/post/critical-thinking-skills-for-children-with-autism$ /library/critical-thinking-skills permanent;
rewrite ^/post/new-year-goals-for-our-children-with-autism$ /library/new-year-goals-2023 permanent;
rewrite ^/post/aia-world-autism-month-celebration$ /library/aia-world-autism-community-day-celebration permanent;
rewrite ^/forms$ /client-forms permanent;
rewrite ^/post/november-aia-update$ /library/november-2022-aia-update permanent;
rewrite ^/post/behavior-modification-techniques-reinforcement-theory$ /library/behavior-modification-techniques-reinforcement-theory permanent;
rewrite ^/post/navigating-the-autism-journey-understanding-and-supporting-our-children-with-autism$ /library/understanding-autism-support permanent;
rewrite ^/post/arizona-institute-for-autism-is-thrilled-to-announce-its-transformation-into-an-integrated-aba-model$ /library/integrated-aba-model-announcement permanent;
rewrite ^/post/repetitive-behaviors-with-children-diagnosed-with-autism$ /library/repetitive-behavior permanent;
rewrite ^/post/asd-sensory-friendly-thanksgiving-recipe$ /library/asd-sensory-friendly-recipe-thanksgiving-pumpkin-cake permanent;
rewrite ^/post/toilet-training-for-a-child-with-autism-using-applied-behavior-analysis-aba$ /library/aba-toilet-training-child-autism permanent;
rewrite ^/post/new-year-2024-holiday-and-autism$ /library/new-year-2024-autism-holiday-tips permanent;
rewrite ^/post/understanding-sensory-processing-in-the-context-of-aba-therapy$ /library/sensory-processing permanent;
rewrite ^/post/enhancing-generalization-for-broader-impact$ /library/enhancing-generalization-skills permanent;
rewrite ^/post/asd-sensory-friendly-recipes-pancakes$ /library/asd-sensory-friendly-recipes-pancakes permanent;
rewrite ^/post/the-benefits-of-aba-therapy-for-children-with-autism$ /library/aba-therapy-benefits permanent;
rewrite ^/post/meet-rula-diab-board-certified-behavior-analyst-bcba$ /library/meet-rula-diab-bcba permanent;
rewrite ^/post/integrity-empowerment-and-excellence-arizona-institute-for-autism-expands-to-new-office$ /library/new-aia-scottsdale-office permanent;
rewrite ^/post/community-highlights-meet-rula-diab-of-arizona-institute-for-autism$ /library/community-highlight-meet-rula-diab permanent;
rewrite ^/post/navigating-dtt-and-net-in-aba-therapy$ /library/aba-therapy-dtt-net-guide permanent;
rewrite ^/post/benefits-of-prompting-and-parenting-in-aba-therapy$ /library/aba-therapy-prompting-parenting-benefits permanent;
rewrite ^/post/building-rapport-with-a-child-in-aba-therapy-the-key-to-fun-engaging-and-effective-sessions$ /library/autism-therapy-rapport-strategies permanent;
rewrite ^/post/exploring-behavior-management-and-understanding-the-functions-of-behavior$ /library/behavior-management-functions-guide permanent;
rewrite ^/post/navigating-back-to-school-understanding-antecedent-and-consequence-interventions-for-families-with$ /library/aba-school-readiness-guide permanent;
rewrite ^/post/proactive-and-reactive-strategies-in-aba$ /library/proactive-reactive-aba-strategies-guide permanent;
rewrite ^/post/individualized-aba-therapy$ /library/individualized-aba-therapy permanent;
rewrite ^/post/parental-self-care-for-autism-families$ /library/autism-family-self-care-tips permanent;
rewrite ^/post/teaching-self-advocacy-through-aba-empowering-children-to-express-their-needs$ /library/autism-self-advocacy-skills-aba permanent;
rewrite ^/ar/library/author/rula-diab-ar$ https://www.azinstitute4autism.com/ar/library/author/rula-diab permanent;
rewrite ^/locations$ /contact permanent;
rewrite ^/schedule/consultation$ /schedule-consultation permanent;
rewrite ^/e2ae5722f9ae40e89a9ebb8d53200e66\.txt$ https://www.azinstitute4autism.com/hubfs/e2ae5722f9ae40e89a9ebb8d53200e66.txt permanent;
rewrite ^/parent-guide$ /library/parents-guide-to-autism-and-aba permanent;
## Existing generated migration redirects follow. They include the remaining
## three rules from the HubSpot export, plus current page-one aliases.
rewrite ^/aba$ /aba-therapy permanent;
rewrite ^/autismevaluations$ /autism-evaluations permanent;
rewrite ^/learnersocialclub$ /learner-social-club permanent;
rewrite ^/library/page/1$ /library permanent;
rewrite ^/es/library/page/1$ /es/library permanent;
rewrite ^/ar/library/page/1$ /ar/library permanent;
rewrite ^/library/author/rula-diab/page/1$ /library/author/rula-diab permanent;
rewrite ^/es/library/author/rula-diab/page/1$ /es/library/author/rula-diab permanent;
rewrite ^/ar/library/author/rula-diab/page/1$ /ar/library/author/rula-diab permanent;
Loaded 100 of 479 files, more files were not shown because too many files have changed in this diff. Show more