From 5eb4426d30c2796628b0c8770cd8929438e29e6d Mon Sep 17 00:00:00 2001 From: Andre Cobham Date: Tue, 9 Jun 2026 18:54:57 +0200 Subject: [PATCH] Update SOPs: consolidate index, clean client data, set Imagen as default - README: rewrite index to reflect actual files (STACK/CONTENT/OPTIMIZATION); remove 15 dead links to old numbered SOPs; add subdirectory table; update image gen to Google Imagen as default - STACK: fix wp-divi-pipeline script paths; genericize vibrantyou/domain examples; strip pre-existing em dashes throughout - CONTENT: update image generation default to Google Imagen API with allotted quota - image-gen-workflow: remove client-specific cobhamtech data; generalize brand palette step; update date - wp-divi-pipeline-to-am-stack: remove vibrantyou.yoga client data block; fix Related SOPs links to current files --- CONTENT.md | 2 +- README.md | 106 +++++------- STACK.md | 190 ++++++++++----------- image-gen-workflow/00-workflow-overview.md | 45 ++--- image-gen-workflow/01-model-selection.md | 34 ++-- local-image-generation/README.md | 14 +- wp-divi-pipeline-to-am-stack/README.md | 50 ++---- 7 files changed, 190 insertions(+), 251 deletions(-) diff --git a/CONTENT.md b/CONTENT.md index f469630..bf7b14e 100644 --- a/CONTENT.md +++ b/CONTENT.md @@ -82,7 +82,7 @@ Hero images: unique per page, named hero-{page-slug}.webp. ## Image Generation -Preferred source: local ComfyUI (FLUX.1 Schnell) or Google Imagen API. +Default source: Google Imagen API (imagen-4.0-generate-001) with allotted quota per project. Every generated image passes a vision validation check for people/faces before being saved. diff --git a/README.md b/README.md index 6d56b81..1950684 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,81 @@ -# Arising Media — Web Design SOPs +# Arising Media Web Design SOPs -Standard operating procedures for building, migrating, and deploying websites -the Arising Media way. Reference `stack-selector.json` FIRST to pick the correct -stack before touching any other SOP. +Standard operating procedures for building, migrating, and deploying websites the Arising Media way. Reference `stack-selector.json` FIRST to pick the correct stack before touching any other SOP. ## Stack selector (read this first) -`stack-selector.json` — machine-readable + human-readable decision guide. -Covers all three stacks, approved colors, section types, DB guidance, hot-copy commands. +`stack-selector.json`: machine-readable + human-readable decision guide. Covers all three stacks, approved colors, section types, DB guidance, hot-copy commands. -## Two primary stacks (2026-05-21 standard) +## Primary SOP files -### Stack A — PHP Router + SQLite (50+ page sites) -**Reference: `arisingmedia.us`** — 10,000+ pages, single router, SQLite content DB. -Edit one template → all pages in that class update instantly. No find-and-replace. -Architecture diagram: `arisingmedia.us/.planning/RENDER_ARCHITECTURE.html` +| File | Covers | +|------|--------| +| `STACK.md` | Architecture, project structure, build pipeline, WP migration, Docker/nginx deployment, cPanel deployment, DNS/email, form handling, PHP app stack | +| `CONTENT.md` | Writing standards, tone by sector, healthcare credential rules, copy structure, image standards, image generation, prompt engineering | +| `OPTIMIZATION.md` | Mobile responsive, breakpoints, SEO meta, schema.org, robots.txt, sitemap, testing/verification, performance standards | + +## Three stacks (2026-05-21 standard) + +### Stack A: PHP Router + SQLite (50+ page sites) +Reference: `arisingmedia.us`. 10,000+ pages, single router, SQLite content DB. +Edit one template and all pages in that class update instantly. Build standard: `arisingmedia.us/.planning/WEBSITE_BUILD_STANDARD.md` -SOP: `15-php-router-sqlite-standard.md` +Stack A uses raw docker commands only. No docker compose. -### Stack B — Static HTML (fewer than 50 pages) -**Reference: `lahrcarpetcleaning.com`** — universal Docker + cPanel deployment. +### Stack B: Static HTML (fewer than 50 pages) +Reference: `lahrcarpetcleaning.com`. Universal Docker + cPanel deployment. Every page is an HTML file on disk. Simple, portable, no server-side requirements. -SOP: `01-project-structure.md`, `03-build-pipeline.md`, `08-deployment-docker.md` -### Stack C — PHP App (file processing, auth, payments) -**Reference: `quickconvert.us`** -SOP: `14-php-app-stack.md` +### Stack C: PHP App (file processing, auth, payments) +Reference: `quickconvert.us` +See STACK.md PHP App Stack section. -## Index +## Subdirectories -1. [00-stack-philosophy.md](00-stack-philosophy.md) — Why static HTML + vanilla JS + Python tooling, what we never use -2. [01-project-structure.md](01-project-structure.md) — Folder layout: flat HTML (Docker) vs directory-style (cPanel). Lahr reference structure. -3. [02-wordpress-to-html-migration.md](02-wordpress-to-html-migration.md) — The migration playbook -4. [03-build-pipeline.md](03-build-pipeline.md) — JSON data + HTML template + Python build script -5. [04-content-rules.md](04-content-rules.md) — Writing standards (no em-dashes, no fake metrics) -6. [05-mobile-responsive.md](05-mobile-responsive.md) — Breakpoints, mobile nav, viewport testing -7. [06-seo-meta.md](06-seo-meta.md) — Title, meta, canonical, keywords, schema, og:, robots.txt, sitemap. Includes lahr examples. -8. [07-form-handling.md](07-form-handling.md) — Resend API + Python stdlib service pattern -9. [08-deployment-docker.md](08-deployment-docker.md) — Universal deployment: Docker+nginx (Path A) AND cPanel+Apache (Path B). Universal project checklist. -10. [09-domain-email-dns.md](09-domain-email-dns.md) — Resend domain verification, SPF/DKIM/DMARC -11. [10-testing-verification.md](10-testing-verification.md) — Playwright checks before declaring done -12. [11-healthcare-regulated-credentials.md](11-healthcare-regulated-credentials.md) — Licensure copy compliance for healthcare clients (MHC-LP, LMHC, supervision disclosure) -13. [12-image-assets.md](12-image-assets.md) — WebP requirement, sizing targets, local generation (FLUX.1 Schnell), convert-to-webp.py -14. [13-reference-site-visual-audit.md](13-reference-site-visual-audit.md) — Playwright Firefox scroll-capture + frame-strip + pin-transition annotation. Output skeleton + schema mapping for any client-cited reference URL. -15. [14-php-app-stack.md](14-php-app-stack.md) — When to use PHP + Docker instead of static HTML. Server-side processing, encryption, auth patterns. +| Directory | Purpose | +|-----------|---------| +| `local-image-generation/` | Full local pipeline: ComfyUI setup, FLUX.1 Schnell images, Wan 2.2 video, prompt guide, quality levers | +| `image-gen-workflow/` | Cloud API workflow (Google Imagen 4). Paid client budgets only. | +| `wp-divi-pipeline-to-am-stack/` | End-to-end pipeline: .wpress archive to Stack A deployment | +| `tools/` | Shared scripts (verify-protection.sh, etc.) | +| `build/` | Build utilities | -## Image generation workflow +## Image generation -See [local-image-generation/](local-image-generation/) for the full local pipeline: -- [01-comfyui-setup.md](local-image-generation/01-comfyui-setup.md) — ComfyUI install, venv, GPU notes -- [02-flux-images.md](local-image-generation/02-flux-images.md) — FLUX.1 Schnell image pipeline -- [03-wan-video.md](local-image-generation/03-wan-video.md) — Wan 2.2 image-to-video pipeline -- [04-prompt-guide.md](local-image-generation/04-prompt-guide.md) — Lens, angle, depth-of-field prompt patterns -- [05-quality-levers.md](local-image-generation/05-quality-levers.md) — Prompt, steps, model size: decision matrix for fixing output quality +Default: Google Imagen API (imagen-4.0-generate-001) with allotted quota per project. +See `image-gen-workflow/` for the workflow, model selection, and prompt patterns. -Default stack (free, no API cost): FLUX.1 Schnell GGUF (images) + Wan 2.2 GGUF (video) via ComfyUI -All output: `.webp` only — see `12-image-assets.md` - -Cloud APIs (Google Veo, Imagen 4, Gemini video): only when client has explicit paid media budget. -Local generation is the default for all Arising Media client projects. +All output: `.webp` only in production. ## Universal project file checklist -Every project must include ALL of these before first commit: +Every project must include ALL of these before first deploy: ``` -Dockerfile Docker/VPS — nginx web container -docker-compose.yml Docker/VPS — service orchestration -nginx.conf Docker/VPS — routing, security headers, gzip -.htaccess cPanel/Apache — clean URLs, deny sensitive files -.cpanel.yml cPanel Git — copy files to webroot on deploy +Dockerfile Docker/VPS: nginx web container +docker-compose.yml Stack B/C only. Stack A uses raw docker commands. +nginx.conf Docker/VPS: routing, security headers, gzip +.htaccess cPanel/Apache: clean URLs, deny sensitive files +.cpanel.yml cPanel Git: copy files to webroot on deploy .dockerignore keeps secrets and tools out of Docker image .gitignore keeps .env and secrets out of git robots.txt both paths sitemap.xml both paths -llms.txt both paths — AI crawler documentation (see 06-seo-meta.md) +llms.txt both paths. AI crawler documentation (see OPTIMIZATION.md) 404.html both paths 500.html both paths ``` ## Reference projects -- `lahrcarpetcleaning.com` — **primary reference**: universal deployment, directory-style URLs, WebP images, cPanel Git, mobile nav, FLUX image generation -- `floorithardwoodfloors.com` — first WP-to-static migration with Docker stack -- `backforge.nl` — simpler static site, no form API +- `lahrcarpetcleaning.com`: primary reference. Universal deployment, directory-style URLs, WebP images, cPanel Git, mobile nav, FLUX image generation. +- `arisingmedia.us`: Stack A reference. PHP router, SQLite, 10,000+ pages. +- `quickconvert.us`: Stack C reference. PHP app, Stripe, encryption, auth. ## When to deviate These SOPs are the default. Deviate only when: -- The client explicitly requires a different stack (CMS-managed editing, e-commerce with Shopify/Woo, etc.) -- A required feature literally cannot be done with this stack +- The client explicitly requires a different stack (CMS-managed editing, e-commerce, etc.) +- A required feature cannot be done with this stack -Document the deviation in the project's own `README.md` so future maintainers -know what is and is not standard. +Document the deviation in the project's own `README.md`. diff --git a/STACK.md b/STACK.md index 0633c31..be4cfb2 100644 --- a/STACK.md +++ b/STACK.md @@ -1,4 +1,4 @@ -# STACK — Architecture, Deployment, and Build Pipeline +# STACK: Architecture, Deployment, and Build Pipeline Author: Andre Cobham / Arising Media Updated: 2026-06-09 @@ -6,19 +6,19 @@ Updated: 2026-06-09 Two primary stacks. Pick based on page count and update frequency. -### Stack A — PHP Router + SQLite (50+ pages, standard as of 2026-05-21) +### Stack A: PHP Router + SQLite (50+ pages, standard as of 2026-05-21) -- **PHP Router** — `router.php` dispatches every content URL to the correct PHP template. Edit one template = entire page class updates on next request. No find-and-replace. No file edits. -- **SQLite** — single-file content DB. `pages.sqlite` holds all page content (title, meta, sections JSON, schema). 10,000 rows = 5MB. Sub-millisecond reads. No server process. -- **Vanilla JavaScript** — no frameworks. `fetch`, `IntersectionObserver`, `querySelector` -- **Plain CSS** — `tokens.css` (design tokens) + `main.css` (components). No Sass, no Tailwind -- **Docker + nginx** — nginx routes `/assets/*` directly; all content URLs → PHP-FPM → router.php -- **Resend** — transactional email via `/api/contact.php` -- **Reference:** `arisingmedia.us` — 10,000+ pages +- **PHP Router**: `router.php` dispatches every content URL to the correct PHP template. Edit one template = entire page class updates on next request. No find-and-replace. No file edits. +- **SQLite**: single-file content DB. `pages.sqlite` holds all page content (title, meta, sections JSON, schema). 10,000 rows = 5MB. Sub-millisecond reads. No server process. +- **Vanilla JavaScript**: no frameworks. `fetch`, `IntersectionObserver`, `querySelector` +- **Plain CSS**: `tokens.css` (design tokens) + `main.css` (components). No Sass, no Tailwind +- **Docker + nginx**: nginx routes `/assets/*` directly; all content URLs → PHP-FPM → router.php +- **Resend**: transactional email via `/api/contact.php` +- **Reference:** `arisingmedia.us`: 10,000+ pages -### Stack B — Static HTML (fewer than 50 pages) +### Stack B: Static HTML (fewer than 50 pages) -- **Static HTML** — every page is a `.html` file on disk +- **Static HTML**: every page is a `.html` file on disk - Same JS, CSS, Docker, nginx, Resend as Stack A - Python 3 stdlib for build scripts (no pip) - **Reference:** `lahrcarpetcleaning.com` @@ -36,11 +36,11 @@ Two primary stacks. Pick based on page count and update frequency. ### Why This Stack -1. **Performance** — a static HTML page with vanilla JS loads in <100ms with no parse cost from frameworks -2. **Longevity** — no dependency rot. A site we build today still works in 10 years with no maintenance -3. **Security** — no `npm audit` warnings, no supply-chain attack vectors, no transitive deps to patch -4. **Auditability** — every line on the site is something we wrote and can read in plain text -5. **Hosting** — a static folder + tiny Python container fits in the smallest VM tier any provider sells +1. **Performance**: a static HTML page with vanilla JS loads in <100ms with no parse cost from frameworks +2. **Longevity**: no dependency rot. A site we build today still works in 10 years with no maintenance +3. **Security**: no `npm audit` warnings, no supply-chain attack vectors, no transitive deps to patch +4. **Auditability**: every line on the site is something we wrote and can read in plain text +5. **Hosting**: a static folder + tiny Python container fits in the smallest VM tier any provider sells ### When to Add a Server-Side Service @@ -121,7 +121,7 @@ Contains ONLY what's needed to run `docker compose up`. ├── api/ # form-submit Python service (if used) │ ├── server.py │ ├── Dockerfile -│ ├── .env # gitignored — Resend key, etc. +│ ├── .env # gitignored: Resend key, etc. │ └── .env.example ├── Dockerfile # nginx web container ├── nginx.conf @@ -145,7 +145,7 @@ notes, raw assets). This is the dev/maintenance copy. NOT what gets deployed. Build scripts, JSON data, and notes go into `.planning/` to keep root clean and prevent accidental web exposure. -### URL Structure — Two Valid Patterns +### URL Structure: Two Valid Patterns #### Pattern A: Flat HTML (default for Docker/nginx projects) @@ -156,7 +156,7 @@ Why flat: - One file = one page, no `/index.html` confusion - Easier sitemap generation - `` links are unambiguous -- Crawl budget benefit — Google indexes one URL per page, not two +- Crawl budget benefit: Google indexes one URL per page, not two #### Pattern B: Directory-style (default for cPanel/Apache projects) @@ -242,9 +242,9 @@ directly. Build scripts are for repetition, not for everything. Three files per template family: -1. **`data/{thing}.json`** — array of objects, one per page -2. **`{thing}/_template.html`** — HTML with `{{placeholder}}` markers -3. **`build_{thing}.py`** — stdlib Python, stamps template with data +1. **`data/{thing}.json`**: array of objects, one per page +2. **`{thing}/_template.html`**: HTML with `{{placeholder}}` markers +3. **`build_{thing}.py`**: stdlib Python, stamps template with data #### Example: locations.json @@ -327,7 +327,7 @@ if __name__ == "__main__": ### Rules 1. **Source of truth is JSON, not HTML.** When content needs to change, edit the - JSON and re-run the build script. Never hand-edit a generated `.html` file — + JSON and re-run the build script. Never hand-edit a generated `.html` file : the next build will overwrite your changes. 2. **Generated files land in the same folder as their template.** Do not nest @@ -345,7 +345,7 @@ if __name__ == "__main__": 5. **Build is idempotent.** Running it twice produces identical files. -### Stamping Rules — Escaping +### Stamping Rules: Escaping When a JSON value gets stamped into an HTML attribute or ``, special characters can break the page. Use these rules: @@ -376,20 +376,20 @@ After build, sync the rendered files to deployment. The playbook for migrating a WordPress (Divi, Elementor, classic, whatever) site to vanilla static HTML. -### Phase 1 — Capture Source +### Phase 1: Capture Source Before touching anything, capture the current site so nothing is lost. -1. **Database dump** — `wp db export ${domain}.sql --add-drop-table` -2. **Wp-content snapshot** — tar the entire `wp-content/` (themes, plugins, uploads) -3. **Crawl the live site** — use `wget --mirror --convert-links --adjust-extension --page-requisites --no-parent https://{domain}` to capture rendered HTML + all assets -4. **Inventory pages** — list every URL returning 200 (use the sitemap if it has one) -5. **Inventory forms** — note every Gravity Form / Contact Form 7 / etc. field-by-field -6. **Inventory dynamic features** — search, comments, members, anything truly dynamic +1. **Database dump**: `wp db export ${domain}.sql --add-drop-table` +2. **Wp-content snapshot**: tar the entire `wp-content/` (themes, plugins, uploads) +3. **Crawl the live site**: use `wget --mirror --convert-links --adjust-extension --page-requisites --no-parent https://{domain}` to capture rendered HTML + all assets +4. **Inventory pages**: list every URL returning 200 (use the sitemap if it has one) +5. **Inventory forms**: note every Gravity Form / Contact Form 7 / etc. field-by-field +6. **Inventory dynamic features**: search, comments, members, anything truly dynamic Save all of this in the project's `.planning/` folder. -### Phase 2 — Decide What to Keep +### Phase 2: Decide What to Keep Re-design pass. Most WP sites have: - Bloated copy → cut by 30-50% @@ -400,7 +400,7 @@ Re-design pass. Most WP sites have: Show the client a wireframe of the simplified structure before building anything. -### Phase 3 — Information Architecture +### Phase 3: Information Architecture Standard structure for a small business: @@ -419,19 +419,19 @@ Standard structure for a small business: For each location and each service: one flat `.html` page generated from JSON + template. -### Phase 4 — Build +### Phase 4: Build -1. Set up source folder per `01-project-structure.md` +1. Set up source folder per the Project Structure section in STACK.md 2. Write `assets/css/main.css` (variables, reset, typography, layout) 3. Write `assets/css/components.css` (header, footer, hero, cards, forms) 4. Write `components/header.html` and `components/footer.html` 5. Write `assets/js/components.js` (fetch + inject header/footer) 6. Write `assets/js/main.js` (scroll animations, anything page-wide) -7. Build `index.html` first — this is the design system in working form +7. Build `index.html` first: this is the design system in working form 8. Generate location and service detail pages from JSON 9. Build remaining pages: about, contact, reviews, blog index -### Phase 5 — Forms +### Phase 5: Forms If the WP site had Gravity Forms or similar, build a vanilla replacement: - HTML form in `contact/index.html` (and inline on service/location pages if needed) @@ -439,7 +439,7 @@ If the WP site had Gravity Forms or similar, build a vanilla replacement: - POST to `/api/estimate` (or similar) handled by Python stdlib service - Server-side validation, reCAPTCHA verification, send via Resend -### Phase 6 — SEO Parity +### Phase 6: SEO Parity Before launch, every old URL must either: - Have a matching new URL with the same or better content, OR @@ -461,7 +461,7 @@ Per-page parity checklist: - Image alt text preserved or improved - Schema.org JSON-LD added (`LocalBusiness`, `Service`, `BreadcrumbList`) -### Phase 7 — Switch DNS / Cutover +### Phase 7: Switch DNS / Cutover 1. Deploy the static site to a separate URL first (`new.{domain}`) for client review 2. Once approved, point production DNS to the new container @@ -469,16 +469,16 @@ Per-page parity checklist: 4. Submit new sitemap to Google Search Console 5. Use Search Console URL inspection on 5-10 key pages to confirm indexing -### Phase 8 — Post-Launch +### Phase 8: Post-Launch - Monitor Search Console for crawl errors / 404s, fix in nginx as redirects -- Monitor form submissions — first real lead through the new form is the +- Monitor form submissions: first real lead through the new form is the ultimate "it works" check - Decommission WP only after 30 days of clean operation ### What NOT to Do -- Do not run a "headless WordPress" or "WordPress as API" — that defeats the +- Do not run a "headless WordPress" or "WordPress as API": that defeats the whole point. Static means static. - Do not use a static-site-generator tool (Hugo, 11ty, Jekyll, Astro, Next.js static export). We hand-write HTML and use small Python build scripts only @@ -506,7 +506,7 @@ Takes a single `.wpress` archive (All-in-One WP Migration backup) and produces: The goal is NOT a 1:1 copy. The goal is: 1. Preserve all content, SEO equity, and brand identity -2. ENHANCE the design — cleaner, faster, more modern +2. ENHANCE the design: cleaner, faster, more modern 3. Remove all WordPress / Divi bloat (plugin CSS, shortcode residue, 300KB JS bundles) 4. Produce a site that loads in <2s on mobile and scores 95+ on Lighthouse @@ -551,14 +551,14 @@ All scripts live in `.am-webdesign-sops/wp-divi-pipeline/scripts/`. | `extract_design.py` | 4 | Pull Divi theme options → design-system.json | | `extract_media.py` | 5 | Catalog uploads/, emit media-manifest.json | | `convert_images.py` | 5 | Batch convert images → WebP | -| `run_pipeline.sh` | 0-7 | Master script — runs all phases in order | +| `run_pipeline.sh` | 0-7 | Master script: runs all phases in order | ### Per-Project Working Directory ``` {domain}/ └── .planning/ - ├── vibrantyou-yoga-YYYYMMDD-*.wpress ← source archive (never modify) + ├── {domain}-YYYYMMDD-*.wpress ← source archive (never modify) ├── wpress-extract/ ← Phase 1 output (gitignored) │ ├── package.json ← archive metadata │ ├── database.sql ← MySQL dump @@ -593,7 +593,7 @@ The archive ends when a header of all null bytes is encountered, or EOF. Extraction script: ```bash -python3 /home/sirdrez/arisingmedia-websites/.am-webdesign-sops/wp-divi-pipeline/scripts/extract_wpress.py \ +python3 /home/sirdrez/arisingmedia-websites/.am-webdesign-sops/wp-divi-pipeline-to-am-stack/scripts/extract_wpress.py \ /home/sirdrez/arisingmedia-websites/{domain}/.planning/{file}.wpress \ /home/sirdrez/arisingmedia-websites/{domain}/.planning/wpress-extract/ ``` @@ -610,9 +610,9 @@ python3 /home/sirdrez/arisingmedia-websites/.am-webdesign-sops/wp-divi-pipeline/ ``` Outputs three files into `.planning/data/`: -- `pages.json` — all published pages/posts with content and SEO meta -- `design-system.json` — colors, fonts, Divi settings -- `site-info.json` — domain, plugin list, WP version, Divi version +- `pages.json`: all published pages/posts with content and SEO meta +- `design-system.json`: colors, fonts, Divi settings +- `site-info.json`: domain, plugin list, WP version, Divi version ### Divi 5 Content Extraction @@ -654,7 +654,7 @@ Strip Divi class/attribute noise using `clean_divi_html()` from `divi_to_html.py from divi_to_html import clean_divi_html, rewrite_internal_links cleaned = clean_divi_html(raw_html) -cleaned = rewrite_internal_links(cleaned, staging_hosts=("vibrantyou.yoga",)) +cleaned = rewrite_internal_links(cleaned, staging_hosts=("{domain}",)) ``` ### Design System Extraction @@ -712,13 +712,13 @@ full 5-step scale around the primary hue: Map extracted Divi content into AM HTML templates. Build order: -1. `src/assets/css/main.css` — design tokens, reset, typography, layout grid -2. `src/assets/css/components.css` — header, footer, hero, cards, forms, nav -3. `src/components/header.html` — navigation -4. `src/components/footer.html` — footer links, contact info -5. `src/assets/js/components.js` — fetch + inject header/footer -6. `src/assets/js/main.js` — scroll animations, intersection observer -7. `src/index.html` — home page (this IS the design system in working form) +1. `src/assets/css/main.css`: design tokens, reset, typography, layout grid +2. `src/assets/css/components.css`: header, footer, hero, cards, forms, nav +3. `src/components/header.html`: navigation +4. `src/components/footer.html`: footer links, contact info +5. `src/assets/js/components.js`: fetch + inject header/footer +6. `src/assets/js/main.js`: scroll animations, intersection observer +7. `src/index.html`: home page (this IS the design system in working form) 8. Remaining pages: about, classes, contact, blog 9. `src/robots.txt`, `src/sitemap.xml`, `src/404.html`, `src/500.html` @@ -790,7 +790,7 @@ Priority order for SEO fields: 2. `post_title` with AM format appended: `{Title} | {Brand Name}` 3. Never leave title as the raw WP default -Rank Math title templates use `%` tokens — strip them and rebuild: +Rank Math title templates use `%` tokens: strip them and rebuild: ```python import re @@ -837,7 +837,7 @@ grep -r "et_pb_\|wp:divi" $SITE --include="*.html" ### Run Order (Complete Execution Sequence) ```bash -export DOMAIN="vibrantyou.yoga" +export DOMAIN="{domain}" export PROJECT="/home/sirdrez/arisingmedia-websites/$DOMAIN" export SOPS="/home/sirdrez/arisingmedia-websites/.am-webdesign-sops" export WPRESS=$(ls $PROJECT/.planning/*.wpress | head -1) @@ -854,7 +854,7 @@ python3 $SOPS/wp-divi-pipeline/scripts/analyze_db.py "$PROJECT/.planning/wpress- # Phase 3: Content extraction (Divi 5 example) python3 $SOPS/wp-divi-pipeline/scripts/extract_divi5.py "$PROJECT/.planning/data/pages.json" "$PROJECT/.planning/data/content/" -# Phase 4: Design system (manual — read design-system.json, write main.css) +# Phase 4: Design system (manual: read design-system.json, write main.css) # Phase 5: Media migration find $PROJECT/.planning/wpress-extract/uploads -type f \( -name "*.jpg" -o -name "*.png" \) | \ @@ -870,7 +870,7 @@ for img in *.jpg *.png; do cwebp -q 82 "$img" -o "${img%.*}.webp" && rm "$img" done -# Phase 6: Build HTML (manual — per 05-content-migration.md) +# Phase 6: Build HTML (manual: per 05-content-migration.md) # Phase 7: SEO audit cd $PROJECT/src @@ -930,17 +930,17 @@ Port assignments are unique per project. Track in ### Dockerfile (nginx web container) -CRITICAL — the Dockerfile must explicitly list which folders to copy. Never use +CRITICAL: the Dockerfile must explicitly list which folders to copy. Never use `COPY . /usr/share/nginx/html/` because that copies `.env`, `Dockerfile`, build scripts, etc. into the web root where they become URL-accessible. ```dockerfile FROM nginx:alpine -# nginx config — server-only, never served as a static file +# nginx config: server-only, never served as a static file COPY nginx.conf /etc/nginx/conf.d/default.conf -# Public website only — explicit list, no wildcards +# Public website only: explicit list, no wildcards COPY index.html /usr/share/nginx/html/ COPY assets /usr/share/nginx/html/assets/ COPY components /usr/share/nginx/html/components/ @@ -975,7 +975,7 @@ server { root /usr/share/nginx/html; index index.html; - # Defense in depth — deny dotfiles, configs, scripts, source files + # Defense in depth: deny dotfiles, configs, scripts, source files location ~ /\. { deny all; return 404; @@ -989,7 +989,7 @@ server { return 404; } - # API proxy — strip /api/ prefix, forward to Python service + # API proxy: strip /api/ prefix, forward to Python service location /api/ { proxy_pass http://api:3001/; proxy_http_version 1.1; @@ -1000,7 +1000,7 @@ server { proxy_connect_timeout 5s; } - # Flat HTML routing — /locations/buffalo serves /locations/buffalo.html + # Flat HTML routing: /locations/buffalo serves /locations/buffalo.html location / { try_files $uri $uri/ $uri.html =404; } @@ -1100,10 +1100,10 @@ scripts, `.git/`, etc.) and fails if any returns 200. ``` Exit codes: -- `0` PASS — every sensitive path 404, every required path reachable. -- `0` PASS (with warnings) — protection clean but `/robots.txt` or +- `0` PASS: every sensitive path 404, every required path reachable. +- `0` PASS (with warnings): protection clean but `/robots.txt` or `/sitemap.xml` missing (content gap, not a leak). -- `1` FAIL — at least one sensitive path returned 200, or `/` is unreachable. +- `1` FAIL: at least one sensitive path returned 200, or `/` is unreachable. Run it manually after every `docker compose up -d --build`. Wire it into CI once the site has a remote pipeline. Treat a FAIL as a deploy rollback. @@ -1132,7 +1132,7 @@ compose project: docker stop {container-name} docker rm {container-name} -# Now bring up from the renamed folder — clean start +# Now bring up from the renamed folder: clean start docker compose -f /path/to/renamed-folder/docker-compose.yml up -d ``` @@ -1152,7 +1152,7 @@ WHM, Bluehost, HostGator, SiteGround, etc.) instead of a VPS running Docker. ### Key Rule: Repo Path ≠ Webroot cPanel Git requires an EMPTY directory as the repository path. The webroot -(`public_html/{domain}/`) is never the repo path — cPanel rejects it if it +(`public_html/{domain}/`) is never the repo path: cPanel rejects it if it already contains files. ``` @@ -1165,7 +1165,7 @@ Deploy target (webroot): /home/{username}/public_html/{domain}/ 1. cPanel → Git Version Control → Create Repository 2. Repository Path: `/home/{username}/repositories/{domain}/` (must be empty) 3. Clone URL: your Git remote (GitHub, Bitbucket, etc.) -4. cPanel clones into the repo path — never into the webroot +4. cPanel clones into the repo path: never into the webroot ### .cpanel.yml @@ -1220,7 +1220,7 @@ deployment: 1. Push to the connected remote (GitHub) 2. cPanel → Git Version Control → Manage → Pull or Deploy 3. cPanel runs the `.cpanel.yml` tasks, copying files to webroot -4. Apache serves from webroot automatically — no nginx, no Docker +4. Apache serves from webroot automatically: no nginx, no Docker ### Apache vs nginx @@ -1232,7 +1232,7 @@ Options -Indexes RewriteEngine On # Directory-style URLs: /services/carpet-cleaning/ → index.html inside that folder -# Apache handles this automatically with DirectoryIndex — no extra rules needed +# Apache handles this automatically with DirectoryIndex: no extra rules needed # Deny sensitive files <FilesMatch "\.(py|yml|yaml|md|log|sh|env|conf|dockerfile)$"> @@ -1312,7 +1312,7 @@ Lahrcarpetcleaning.com is the reference implementation for both paths. 1. https://resend.com/domains → **Add Domain** 2. Enter the domain (the one you'll send FROM, not necessarily the website domain) 3. Resend gives 3-4 DNS records. Add them all in Cloudflare (or whatever DNS host) -4. Wait 5-15 minutes, click **Verify** in Resend — all records must show green +4. Wait 5-15 minutes, click **Verify** in Resend: all records must show green ### Records Resend Provides @@ -1324,7 +1324,7 @@ Lahrcarpetcleaning.com is the reference implementation for both paths. (Resend uses Amazon SES under the hood, hence `amazonses.com` in the SPF.) -### DMARC — REQUIRED for Inbox Placement +### DMARC: REQUIRED for Inbox Placement Without DMARC, Gmail flags otherwise-correctly-configured email as suspicious and routes it to spam. Resend doesn't auto-create this record. You must add it. @@ -1334,9 +1334,9 @@ and routes it to spam. Resend doesn't auto-create this record. You must add it. | TXT | `_dmarc` | `v=DMARC1; p=none; rua=mailto:dev@{domain}` | DNS only | Auto | Components: -- `v=DMARC1` — declares a DMARC policy exists -- `p=none` — monitor mode, doesn't reject anything yet (safe to start) -- `rua=mailto:...` — DMARC failure reports go to this inbox (review weekly) +- `v=DMARC1`: declares a DMARC policy exists +- `p=none`: monitor mode, doesn't reject anything yet (safe to start) +- `rua=mailto:...`: DMARC failure reports go to this inbox (review weekly) After 30 days of clean DMARC reports with no false positives, optionally upgrade to `p=quarantine` then `p=reject`. @@ -1389,7 +1389,7 @@ Run this checklist: ### Cloudflare-Specific Notes -The user-agent quirk — Cloudflare in front of Resend's API blocks Python's default +The user-agent quirk: Cloudflare in front of Resend's API blocks Python's default `User-Agent: Python-urllib/3.x`. Always set a custom `User-Agent` in the API request headers. If the DNS provider is Cloudflare, ensure all Resend records have **proxy status: DNS only** @@ -1404,7 +1404,7 @@ Rotate Resend API keys annually: 4. Confirm a test submission still works 5. Revoke the old key in Resend dashboard -### Resend HTTP 403 — Domain Not Verified +### Resend HTTP 403: Domain Not Verified A 403 from the Resend API does NOT mean the API key is wrong. The specific error is: @@ -1435,7 +1435,7 @@ in Cloudflare, then click verify. Old key remains active until they remove it. --- -## Form Handling — Resend +## Form Handling: Resend Static sites can't send email by themselves. Every project that needs a contact form gets a small Python service running in its own Docker container, @@ -1565,11 +1565,11 @@ are deduplicated by Resend automatically. This prevents: - API key in `.env` file, NOT in source control. `.gitignore` it. - API key NEVER reaches the browser bundle (only the server has it) - `.env` file lives in `api/`, NOT in the nginx web root -- Server-side validation on EVERY field — never trust client +- Server-side validation on EVERY field: never trust client - HTML-escape every field rendered into the email body to prevent injection - Rate limit per IP (5 / 15 min default) -- 16 KB body cap — reject anything larger -- 10-second upstream timeout — don't hold connections open +- 16 KB body cap: reject anything larger +- 10-second upstream timeout: don't hold connections open - CORS locked to the production domain only (`Access-Control-Allow-Origin: https://{domain}`) - reCAPTCHA v3 with score threshold (default 0.5) once secret is configured @@ -1650,7 +1650,7 @@ Use this pattern when a project requires server-side processing that static HTML - **PHP 8.3** (php:8.3-fpm-alpine base image) - **Nginx** (Alpine package, same container via supervisord) - **SQLite** (pdo_sqlite extension, no separate DB container needed) -- **libsodium** (built into PHP 8.x — use for all encryption) +- **libsodium** (built into PHP 8.x: use for all encryption) - **ImageMagick** (pecl imagick for image processing) - **msmtp** (SMTP relay for outbound email) - **supervisord** (manages nginx + php-fpm + crond in one container) @@ -1697,19 +1697,19 @@ project/ ### Security Requirements (Non-Negotiable) -**CSRF** — every POST form and API endpoint must verify a CSRF token tied to the session. +**CSRF**: every POST form and API endpoint must verify a CSRF token tied to the session. -**Rate limiting** — two layers: +**Rate limiting**: two layers: 1. nginx: `limit_req_zone` on /api/ (10 req/s, burst 20) 2. PHP: per-IP daily counter in SQLite rate_limits table -**reCAPTCHA v3** — on conversion/upload endpoints. Verify server-side via Google API. Cache result in session (verify once per session, not per request). +**reCAPTCHA v3**: on conversion/upload endpoints. Verify server-side via Google API. Cache result in session (verify once per session, not per request). -**At-rest encryption** — any user-uploaded file must be encrypted before writing to disk. Use `sodium_crypto_secretstream_xchacha20poly1305_*` for files, `sodium_crypto_secretbox` for strings. Key stored in `.env` as `QC_ENCRYPTION_KEY` (32 bytes hex). +**At-rest encryption**: any user-uploaded file must be encrypted before writing to disk. Use `sodium_crypto_secretstream_xchacha20poly1305_*` for files, `sodium_crypto_secretbox` for strings. Key stored in `.env` as `QC_ENCRYPTION_KEY` (32 bytes hex). -**Signed download tokens** — never expose file paths. Issue a 64-char hex token stored in SQLite with expiry and single-use enforcement. +**Signed download tokens**: never expose file paths. Issue a 64-char hex token stored in SQLite with expiry and single-use enforcement. -**Magic link auth** — prefer magic link over password. On register: create account unverified, send verify email, block login until verified. Token: 64-char hex, 1-hour expiry, stored in `magic_tokens` table, consumed on use. +**Magic link auth**: prefer magic link over password. On register: create account unverified, send verify email, block login until verified. Token: 64-char hex, 1-hour expiry, stored in `magic_tokens` table, consumed on use. ### Nginx Security Headers @@ -1720,7 +1720,7 @@ add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.google.com https://www.gstatic.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; form-action 'self' https://checkout.stripe.com;" always; -# Stripe webhook — POST only +# Stripe webhook: POST only location = /api/stripe-webhook.php { limit_except POST { deny all; } } @@ -1741,7 +1741,7 @@ catch (Throwable $e) { /* column already exists */ } ### Stripe Integration - Checkout: create session server-side, redirect to Stripe-hosted page -- Webhook: verify `Stripe-Signature` header using HMAC-SHA256 (implement without Stripe SDK — use curl) +- Webhook: verify `Stripe-Signature` header using HMAC-SHA256 (implement without Stripe SDK: use curl) - Webhook tolerance: 300 seconds (5 min) on timestamp - Register webhook endpoint at: `https://{domain}/api/stripe-webhook.php` - Events to subscribe: `checkout.session.completed`, `customer.subscription.created`, `customer.subscription.updated`, `customer.subscription.deleted`, `invoice.payment_succeeded`, `invoice.payment_failed` diff --git a/image-gen-workflow/00-workflow-overview.md b/image-gen-workflow/00-workflow-overview.md index 7fdbe6b..a166c7b 100644 --- a/image-gen-workflow/00-workflow-overview.md +++ b/image-gen-workflow/00-workflow-overview.md @@ -1,7 +1,6 @@ -# Image Generation Workflow — Arising Media +# Image Generation Workflow: Arising Media -Last updated: 2026-05-10 -Project reference: cobhamtech.com (first full run) +Last updated: 2026-06-09 --- @@ -15,13 +14,13 @@ Standardized process for generating, validating, and deploying AI images across API: Google Gemini (generativelanguage.googleapis.com) SDK: google-genai (NOT the deprecated google-generativeai package) -Draft model: gemini-2.5-flash-image (Nano Banana — Speed Mode) -Final model: imagen-4.0-generate-001 (Imagen 4 — Quality Mode) +Draft model: gemini-2.5-flash-image (Nano Banana: Speed Mode) +Final model: imagen-4.0-generate-001 (Imagen 4: Quality Mode) Format: JPEG, 85% quality, max 1600px wide --- -## Phase 1 — Site Analysis (before any generation) +## Phase 1: Site Analysis (before any generation) Before generating images, read: - index.html (home page structure) @@ -38,14 +37,14 @@ Document this in: 01-model-selection.md (image plan table) --- -## Phase 2 — Prompt Engineering +## Phase 2: Prompt Engineering ### Rules - Always reference the site color palette in the prompt (dark navy, slate blue, gold accents) - Specify "no text" and "no logos" for background images - Specify "photorealistic" for all marketing images - NO PEOPLE. NO FACES. Hardware, infrastructure, and environment only across all client sites -- This applies to all slots: hero, about, services, contact, location — no exceptions +- This applies to all slots: hero, about, services, contact, location: no exceptions - Reason: faces introduce identity/representation risk and age poorly. Hardware stays neutral and professional. ### Prompt structure @@ -54,13 +53,13 @@ Document this in: 01-model-selection.md (image plan table) ### Example (hero background) "Professional enterprise server room, long corridor of dark rack servers with blue LED ambient lighting, deep perspective, dark navy background, cinematic shallow depth of field, no people, photorealistic, ultra detailed" -### cobhamtech.com brand prompt additions -Always append to prompts for this client: -"dark navy and blue ambient lighting, professional, enterprise, no text" +### Per-project brand prompt additions +Append brand-specific color and tone language to every prompt for a given client. +Example: "dark navy and blue ambient lighting, professional, enterprise, no text" --- -## Phase 3 — Generation Script Pattern +## Phase 3: Generation Script Pattern ```python from google import genai @@ -84,16 +83,16 @@ with open('output.jpg', 'wb') as f: Validate: file must be > 10,000 bytes. Anything smaller is an API error or empty response. -CRITICAL — Vision validation is mandatory before saving any image: +CRITICAL: Vision validation is mandatory before saving any image: The toolbox script (ai-imagen-generate.sh) automatically sends each generated image to gemini-2.0-flash for visual inspection. It asks: "Does this image contain people, faces, -hands, silhouettes, or body parts?" If YES — the image is rejected, prompt is tightened, +hands, silhouettes, or body parts?" If YES: the image is rejected, prompt is tightened, and generation retries up to 3 times. Only images that pass inspection are saved. -Claude cannot visually inspect images — the vision validation step is the enforcement gate. +Claude cannot visually inspect images: the vision validation step is the enforcement gate. --- -## Phase 4 — Placement Patterns +## Phase 4: Placement Patterns ### Pattern A: CSS background-image with dark overlay (hero sections) @@ -143,15 +142,15 @@ Implementation: add img to existing grid + expand grid columns --- -## Phase 5 — CSP and nginx Updates +## Phase 5: CSP and nginx Updates Any new image source domain requires a CSP update in nginx.conf. For Google Maps tiles: add `https://*.googleapis.com https://*.gstatic.com` to `img-src` -For self-hosted images: `img-src 'self' data:` is sufficient — no change needed +For self-hosted images: `img-src 'self' data:` is sufficient: no change needed --- -## Phase 6 — Docker Rebuild and Verify +## Phase 6: Docker Rebuild and Verify After every image + HTML change: @@ -192,11 +191,3 @@ Every generation run must produce a log entry in: Log must include: date, client, model, each image file name, prompt used, file size in bytes, placement pattern used, Docker rebuild result. ---- - -## Cobhamtech.com Run Reference - -Container: cobhamtech-site -Port: 8010 -Assets path: /home/sirdrez/arisingmedia-websites/cobhamtech.com/assets/images/ -Color tokens: --ct-black #0c0f18 / --ct-slate #1c2d42 / --ct-blue #2d5a9e / --ct-gold #c79330 diff --git a/image-gen-workflow/01-model-selection.md b/image-gen-workflow/01-model-selection.md index 7286659..33393e3 100644 --- a/image-gen-workflow/01-model-selection.md +++ b/image-gen-workflow/01-model-selection.md @@ -6,7 +6,7 @@ Source: cutout.pro/model-comparison/imagen-vs-nanobanana + Gemini API model audi ## Available Models (via Google Gemini API) -### Imagen 4 — Quality Mode +### Imagen 4: Quality Mode Model ID: `imagen-4.0-generate-001` Also available: `imagen-4.0-ultra-generate-001` @@ -24,7 +24,7 @@ Use for: --- -### Nano Banana (Gemini 2.5 Flash Image) — Speed Mode +### Nano Banana (Gemini 2.5 Flash Image): Speed Mode Model ID: `gemini-2.5-flash-image` Strengths: @@ -40,7 +40,7 @@ Use for: --- -### Imagen 4 Fast — Budget Mode +### Imagen 4 Fast: Budget Mode Model ID: `imagen-4.0-fast-generate-001` Use for: @@ -52,38 +52,26 @@ Use for: ## Recommended Workflow -Step 1 — Draft with Speed Mode (`gemini-2.5-flash-image`) +Step 1: Draft with Speed Mode (`gemini-2.5-flash-image`) Generate 2-4 variations quickly. Confirm composition, subject, and tone. Low cost. -Step 2 — Refine with Quality Mode (`imagen-4.0-generate-001`) +Step 2: Refine with Quality Mode (`imagen-4.0-generate-001`) Take the winning prompt from step 1. Generate final version at full quality. This is the image that goes into the site. -Step 3 — Review against brand palette -Check that image tones align with site color tokens: -- cobhamtech.com: dark navy (#0c0f18), slate (#1c2d42), blue accent (#2d5a9e), gold (#c79330) -- All hero images need to work behind dark overlays +Step 3: Review against brand palette +Check that image tones align with the project's color tokens from `tokens.css`. +All hero images need to work behind dark overlays. -Step 4 — Save to project assets +Step 4: Save to project assets Path convention: `assets/images/{page}-{slot}.jpg` Examples: `hero-bg.jpg`, `about-visual.jpg`, `services-bg.jpg` --- -## Cobhamtech.com Image Plan - -| Slot | File | Page | Prompt Theme | -|------|------|------|--------------| -| Hero background | `hero-bg.jpg` | index.html | Dark server room, blue ambient lighting, depth of field | -| About story | `about-visual.jpg` | about.html | IT professional at clean desk, dual monitors, neutral dark background | -| Services hub | `services-bg.jpg` | services/index.html | Enterprise network infrastructure, abstract, dark | -| Intro visual | `intro-visual.jpg` | index.html | Business and technology handshake, professional setting | - ---- - ## Notes - Never use Nano Banana for final production images on client sites -- Imagen 4 Ultra adds marginal quality gain over standard — not worth the cost for web assets +- Imagen 4 Ultra adds marginal quality gain over standard: not worth the cost for web assets - All images should be exported as JPEG at 85% quality, max 1600px wide, for web performance -- Run generated images through the site CSP — ensure `img-src` allows `self` and `data:` only (no external CDN hotlinking) +- Run generated images through the site CSP: ensure `img-src` allows `self` and `data:` only (no external CDN hotlinking) diff --git a/local-image-generation/README.md b/local-image-generation/README.md index fbe9bbb..b02ee4b 100644 --- a/local-image-generation/README.md +++ b/local-image-generation/README.md @@ -1,15 +1,15 @@ -# Local Image Generation — SOPs +# Local Image Generation: SOPs Complete reference for generating site images locally using ComfyUI. No cloud API required. No per-image cost. Runs on the Arising Media workstation. ## Index -1. [01-comfyui-setup.md](01-comfyui-setup.md) — Installing ComfyUI, venv, GGUF node -2. [02-flux-images.md](02-flux-images.md) — FLUX.1 Schnell image generation pipeline -3. [03-wan-video.md](03-wan-video.md) — Wan 2.2 image-to-video pipeline -4. [04-prompt-guide.md](04-prompt-guide.md) — Prompt patterns for interior/carpet photography -5. [05-quality-levers.md](05-quality-levers.md) — Prompt, steps, model size: what to adjust and when +1. [01-comfyui-setup.md](01-comfyui-setup.md): Installing ComfyUI, venv, GGUF node +2. [02-flux-images.md](02-flux-images.md): FLUX.1 Schnell image generation pipeline +3. [03-wan-video.md](03-wan-video.md): Wan 2.2 image-to-video pipeline +4. [04-prompt-guide.md](04-prompt-guide.md): Prompt patterns for interior/carpet photography +5. [05-quality-levers.md](05-quality-levers.md): Prompt, steps, model size: what to adjust and when ## Quick start (images already set up) @@ -42,5 +42,5 @@ docker compose build --no-cache web && docker compose up -d ## Reference project -`lahrcarpetcleaning.com` — first project using this full pipeline. +`lahrcarpetcleaning.com`: first project using this full pipeline. Scripts: `tools/gen-images-flux.py`, `tools/gen-video-wan.py`, `tools/convert-to-webp.py` diff --git a/wp-divi-pipeline-to-am-stack/README.md b/wp-divi-pipeline-to-am-stack/README.md index 876781c..29be0c4 100644 --- a/wp-divi-pipeline-to-am-stack/README.md +++ b/wp-divi-pipeline-to-am-stack/README.md @@ -1,4 +1,4 @@ -# WP + Divi to AM Stack A Pipeline — SOP Index +# WP + Divi to AM Stack A Pipeline: SOP Index End-to-end playbook for converting any WordPress / Divi site backup (.wpress) into an Arising Media Stack A deployment: PHP router + SQLite + vanilla JS/CSS. @@ -17,23 +17,23 @@ complete ordered execution checklist. | File | Phase | Description | |------|-------|-------------| -| `00-overview.md` | — | Pipeline overview, philosophy, what to extract vs not replicate | +| `00-overview.md` | n/a | Pipeline overview, philosophy, what to extract vs not replicate | | `01-wpress-extraction.md` | 1 | .wpress binary format, extraction script, verification | | `02-database-analysis.md` | 2 | MySQL dump parsing, page inventory, Divi version detection | | `03-divi-content-extraction.md` | 3 | Divi 4 shortcodes vs Divi 5 blocks, extraction scripts | -| `04-design-system-extraction.md` | 4 | Colors, fonts, spacing → tokens.css | +| `04-design-system-extraction.md` | 4 | Colors, fonts, spacing to tokens.css | | `05-content-migration.md` | 5-6 | Section remapping, content staging, seed_databases.py | | `06-media-assets.md` | 5 | Upload migration, WebP conversion, media manifest | | `07-seo-preservation.md` | 7 | Redirect map, Rank Math extraction, schema.org | -| `08-run-order.md` | — | DEPRECATED — superseded by `10-agent-breadcrumbs.md` | -| `09-stack-a-output.md` | — | SQLite schemas, sections_json spec, Divi→AM module mapping | -| `10-agent-breadcrumbs.md` | 0-11 | Ordered agent execution checklist (.wpress → live Docker) | +| `08-run-order.md` | n/a | DEPRECATED. Superseded by `10-agent-breadcrumbs.md` | +| `09-stack-a-output.md` | n/a | SQLite schemas, sections_json spec, Divi to AM module mapping | +| `10-agent-breadcrumbs.md` | 0-11 | Ordered agent execution checklist (.wpress to live Docker) | ## Scripts in scripts/ | Script | Purpose | |--------|---------| -| `migrate.py` | CLI launcher — runs phases 0-6, prints breadcrumbs for 7-11 | +| `migrate.py` | CLI launcher: runs phases 0-6, prints breadcrumbs for 7-11 | | `run_pipeline.sh` | Legacy shell wrapper (pre-migrate.py) | | `extract_wpress.py` | Unpack .wpress binary archive | | `analyze_db.py` | Parse SQL dump → pages.json + design-system.json | @@ -43,39 +43,13 @@ complete ordered execution checklist. ## Key facts about .wpress archives -- Format: Custom sequential binary (NOT zip/tar) — 4377-byte headers +- Format: Custom sequential binary (NOT zip/tar): 4377-byte headers - Table prefix in SQL dump: `SERVMASK_PREFIX_` (placeholder, NOT `wp_`) -- Directory layout: flat — `uploads/`, `themes/`, `plugins/` at archive root (no `wp-content/` wrapper) +- Directory layout: flat: `uploads/`, `themes/`, `plugins/` at archive root (no `wp-content/` wrapper) - Divi 5 stores theme settings in `et_divi` option as PHP-serialized array -## vibrantyou.yoga — extracted data reference - -Site: Vibrant You Yoga (instructor: Meghan) -Domain: https://vibrantyou.yoga -Divi version: 5.0.3 -WP version: 6.9.4 - -Design system: -- Primary: #1a8a7a Dark: #0f5f53 Secondary: #2ea3f2 -- Body: #5a6b68 Headings: #2d2d2d -- Body font: DM Sans 17px / 1.6 lh -- Heading font: DM Serif Display 600 / 36px / 1.2 lh - -Pages to migrate (22 published): -- home, about, classes, schedule, instructors, contact, blog, faq -- book (private sessions), online-yoga, donate -- Drop: video-category, video-tag, search-videos, user-videos, player-embed, - categories, tags, my-bookings (all plugin-generated archive pages) - -Plugins requiring AM replacements: -- Gravity Forms + Stripe → AM HTML form + Python API + Resend -- Events Manager → static schedule table in /schedule/ -- All-in-One Video Gallery → embed YouTube/Vimeo directly or drop - ## Related SOPs -- `../01-project-structure.md` — AM deployment directory layout -- `../02-wordpress-to-html-migration.md` — Original 8-phase WP migration playbook -- `../03-build-pipeline.md` — JSON + template stamping for repeated pages -- `../06-seo-meta.md` — Full `<head>` requirements, schema.org per page type -- `../tools/verify-protection.sh` — Post-deploy security audit +- `../STACK.md`: AM deployment directory layout, build pipeline, WP migration playbook +- `../OPTIMIZATION.md`: Full `<head>` requirements, schema.org per page type +- `../tools/verify-protection.sh`: Post-deploy security audit