Within Reach — Project Planning
Client: Within Reach (Omaha, NE) Platform: WordPress (Custom Theme + ACF Pro)
Project Info
| Job Number | 2025-031 |
| Phase | Active |
| Billable | Yes |
Client Contacts
- TBD — need to confirm primary contact name and email
Site Reference
| Local Path | /Users/edowns/Local Sites/within-reach/app/public/wp-content/themes/withinreach |
| Local URL | http://within-reach.local |
| Production URL | TBD |
| GitHub | grainandmortar/withinreach (private) |
| Theme Docs | See CLAUDE.md at theme root and docs/ folder |
Integrations
| Service | Status | Details |
|---|---|---|
| Harvest | Active | Project 44813951 (Branding + Website Design & Development), Task: Web Development: Coding 16198766 |
| Todoist (Team) | Active | Within Reach (2025-031) — 6c593JgpW3gFMXM7 |
| Todoist (Dev) | Active | Within Reach (2025-031) - Dev — 6gP5X3fxMxH7Hqj2 |
| Masterdoc | Found | Within Reach Master (Drive: Within Reach/2025-031_BrandingWeb/_Notes and client communication). Tabs: Client Logins, Development Notes, Dev Tweaks (source of truth for soft launch tweaks — see Dev Tweaks Workflow below) |
| Basecamp | TBD | Not yet checked |
| Notion | TBD | Not yet checked |
| Figma | Active | Designs reviewed (V3 page, 19 artboards) — node IDs in figma-node-ids.md |
| GoHighLevel / Forms 360 | Active | White-labeled as go360/gothreesixty.io. Location ID: JV92BO7r8Iw0OqhzX3am. PIT token received 2026-04-14, stored in 1Password ("Within Reach - GoHighLevel API (Forms 360)") and in ACF Options (Theme Settings → Integrations). Integration built: see theme/docs/INTEGRATIONS-FORMS-360.md. form_embed module live on /contact/ for testing. |
| Cloudflare | N/A | Not yet launched |
| SendGrid | N/A | Not yet launched |
Vendor Contacts
- Austin Hall — threesixty° (go360 / GoHighLevel white-label), hello@gothreesixty.io, (402) 999-0667. Friend of Eric's.
All Content Doc
Within Reach — All Content — master sheet mapping every page on the site to its copy, design, and status.
- Spreadsheet ID:
1Tjpk-5838zq7zQyryjSwm7lFue6ktMdo4Dh1RHdr7ic - Tab:
Text(single tab, ~30 page rows) - Hierarchy marker: Leading dashes in "Page Name" indicate nav depth (
-- Flourishing Churches & Leadersis a child of- Initiatives).
Columns
| Column | Purpose |
|---|---|
| Page Name | Page title; dashes indicate hierarchy |
| New Slug | Target URL path on the rebuild |
| Previous URL | Live URL on the old site (if it exists) |
| Google Doc with New Copy | Per-page Google Doc where copy is written |
| Link to new layout / design | Figma prototype node link |
| Outline Ready | ☐/☑ — copy outline approved |
| Copy Done | ☐/☑ — copy written (deadline Nov 14) |
| Client Approved | ☐/☑ — client signed off |
How Claude uses it
See /project-notes skill → "All Content Doc Workflow". Trigger phrases like "check the content doc for [page]", "pull the copy for [page]", or "all content doc" resolve here. Default behavior: confirm target page via fuzzy match, fetch the linked Google Doc, warn if Copy Done is FALSE before using it.
Dev Tweaks Workflow (Soft Launch)
Source of truth: Dev Tweaks tab in the Within Reach Masterdoc (sheet ID 1LlnSBT7ZMXy98zR_I0c6XqGaRaUT40qYn5ynkgzXmgY, gid 872268118).
All soft-launch tweaks and client-reported issues get logged here — not Slack, not email, not Basecamp. When Eric says "work on soft launch tweaks" or "knock out the dev tweaks," pull this tab first.
Columns
| Column | Purpose |
|---|---|
| Place | Where on the site (page / module / admin area) |
| Error | What's wrong or what needs to change |
| Who found it? | Initials of reporter (usually BR = Brooke) |
| Who will fix it? | Initials of assignee (ED = Eric, etc.) |
| Completed (initials) | Initials of whoever completed it — leave blank until done |
| Notes | Freeform notes / clarifications |
How Claude uses it
- Pull the tab via
mcp__google-drive__getGoogleSheetContentwith rangeDev Tweaks!A1:Z100. - Filter to rows assigned to ED that are not marked complete.
- Work them via the
/soft-launchskill — one at a time, confirm scope, fix, verify in browser, mark done. - Update the "Completed (initials)" column as each item ships. (Use
updateGoogleSheetto stamp ED in col E.)
Project Status
2026-04-29 (afternoon) — ACF sync drift recovery + Dev Tweaks 99-116 + hero_page migration to JSON
Continuation of the morning's work. Three threads.
ACF sync drift recovery (Rows 99/100). Earlier in the day rows 99/100 (Impact Grid Image + Avatar helper text) were stamped completed on the sheet but the implementation was uncommitted WIP in inc/acfe-compat.php based on a wrong premise (a clone-resolver bug that doesn't actually exist in the current JSON). Reverted the WIP filter; set instructions directly on the source-of-truth fields in acf-json/group_module_impact_grid.json. Verified at runtime that the clone resolver correctly propagates them to group_page_modules. Visually confirmed in wp-admin on Home → Impact Grid module.
Sync drift fix. While investigating, found that 27 of 29 JSON groups had no DB shadow rows — the 2026-04-29 morning bloat-repair commit (b694dbf) had purged every JSON-backed DB row but the JSON→DB re-sync afterward never ran. Wrote inc/dev/sync-acf-json-to-db.php to import every JSON group + export DB-only groups (program_cards, initiative_cards) to JSON. After two non-idempotent runs balloons 670 fields → 5,240, hardened the script to auto-run repair-acf-db.php first. Now safely re-runnable. Bumped CLAUDE.md tripwire from >300 to >800 since the new architecture's healthy baseline is ~670.
Dev Tweaks 102-116 (5 commits). - Rows 102/103 — Featured Block: image helper text (1300×1300px) + new Spacing tab (was hanging at end of Options). - Row 104 — Detail Rows: row image helper text (1600px+). - Row 105 — Image Callout: bg image helper text (1900px+). - Row 106 — Callout Card: Story Video URL moved from above-the-tabs into the Content tab. - Rows 107-113 — Image Callout Banner / Goal Stats / Stats Quote Grid: added Content + Options tabs (modules previously had only Spacing) and reorganized field order. Image helper text on ICB (1900px+) and SQG image_1 (1285×800) / image_2 (1280×1235). - Row 114 — Bio List: Photo helper text bumped 260×260 → 520×520 (2x retina spec). - Row 115 — Partner CTA: helper text on all three images (Large 1040×1480 / Medium 970×580 / Small 530×450). - Row 116 — Module description messages: added the bold-name + short-description pattern to Featured Block, Detail Rows, Image Callout (replaced placeholder "Fields are managed by..." text), Image Callout Banner, Goal Stats, Stats Quote Grid, and Hero: Page. Image + Text CTA already had its description.
Hero: Page migration to JSON. inc/acf/hero_page.php was registering the hero_page layout via runtime PHP filter. The docblock cited the 2026-04-17 ACF auto-save_json incident (which has long since been mitigated by __return_false in inc/acfe-compat.php). Migrated the layout into acf-json/group_page_modules.json, baked the topper-bottom copy and the "Hero: Media" label-mutation into JSON statically, deleted inc/acf/hero_page.php, removed the require from functions.php. Editors can now find Hero: Page in wp-admin → Custom Fields like every other module. form_embed (inc/integrations/ghl.php) follows the same legacy PHP-filter pattern but is left alone for now since it's coupled to GHL API logic.
Status: Tree clean, all four session commits + one morning hardening commit on origin/main (399bb4a, 9482b41, 3cd2fe8, 702f59f, f431fa0). 31 ACF field groups all loaded from JSON, zero DB-only orphans, zero "Sync available" warnings. Dev Tweaks rows 99-116 stamped + green-filled in the sheet.
2026-04-29 — Soft-launch tweaks: topper redesign, ACF DB bloat repair, Forms 360 footer exception
Worked through 13 Dev Tweaks rows (57, 58, 60, 61, 62, 95–100, 101) plus drafted client email for Row 59 (blocked on vendor). Six commits to the theme + skill-level prevention docs.
The standout: ACF DB bloat fix (Row 60). BR reported Hero Text was showing two phantom empty Content + Options tabs that didn't belong. Investigation revealed field_page_modules had 907 child acf-field DB rows (should have been ~50) — and across the whole DB, 1,897 acf-field rows. Source: clone-expansion artifacts accumulated over many sync cycles, plus acf-json/group_module_partner_cta.json was an "empty shell" re-registering field keys that ALSO existed inline in group_page_modules.json. ACF was loading both definitions and stitching one set into the wrong layout. Wrote a web-trigger wrapper for the existing inc/dev/repair-acf-db.php (since wp-cli isn't reachable from host shell on Local), purged 30 JSON-backed groups + 1,874 orphan acf-field rows, deleted the empty-shell JSON. Post-repair: 2 groups + 23 fields preserved (intentional DB-only). Hero Text now shows only its three real tabs.
Prevention codified. Added a bloat row-count check (step 6) to the Post-ACF-change checklist in CLAUDE.md, plus an "if you see fields/tabs from another module, go straight to the playbook" callout. Updated /wordpress-acf skill: symptoms catalog now flags the cross-module tab leak, empty-shell guidance flipped from "harmless leftover" to "actively delete," added the web-wrapper repair pattern. Updated /wordpress-modules skill with a cross-reference. Should prevent future-Claude (and future-me) from spending 30 minutes hunting through JSON before running the bloat check.
Topper seam redo (Row 58). Mike flagged the 1px seam on darker-color toppers. First attempt centered a 2px gradient transition on the SVG plateau — fuzz visible. Redesign: removed the gradient entirely. .module-topper__middle::before now paints a solid rectangle anchored to the bottom with height: calc(100% * 52.83 / 93.76) — the exact ratio the SVG uses for its plateau-to-bottom span. SVG curves and middle bar render as one continuous shape. Verified at 1440 desktop + 375 mobile against navy and dark-green topper instances. Audited the 5 pages Mike flagged for missing toppers; BR had addressed the primary cases; added toppers to closing CTAs on O,NE + LOSD (Row 101).
Forms 360 footer-newsletter exception (Row 59). BR flagged the footer form goes nowhere. Investigation: it's a placeholder form (action="#" with no backend). Designed AJAX → REST proxy → GHL Contacts API approach to preserve the branded card design (the existing "Email Subscription" Forms 360 form requires First/Last/consent fields the footer card can't fit). Discovered the existing PIT only has forms.readonly scope — implementation blocked on Taylor/Austin adding contacts.write. Drafted email (saved to docs/client-comms/2026-04-29-forms-360-api-scope-request.md, sent to both via Gmail draft → Eric pushed). Documented the architectural decision in docs/INTEGRATIONS-FORMS-360.md "Footer Newsletter Exception" section so future-Claude doesn't try to apply the proxy pattern to other forms — every other form on the site stays iframe.
Admin Columns Pro for FAQs (Row 62). Replaced a hand-rolled manage_faq_posts_columns filter with proper AC Pro file-storage layout. Set up inc/admin-columns.php (file-storage filter) and acp-settings/cf_faq_default.php (FAQ list config: column-order with inline-edit + drag-drop sort, title, taxonomy filter, date). BR can now click any Order value and type a new number, or drag rows.
Dashboard module schema cleanup (Rows 61, 95–100). Helper text added to Hero Media Video Thumbnail (650×400), Image+Text CTA Image (≥1080px wide), Impact Grid Image (≥1300×1300) and Avatar (≥400×400 square). Image+Text CTA gained the standard intro-explainer message. Topic Cards "Appearance" tab renamed → "Options" for consistency. Stat Callout's Background Color + Text Color Scheme moved into a proper Options tab (was hanging at the end of Spacing).
Forms 360 last-refreshed UI. Integrations options page now displays "Last refreshed: April 29, 2026 at 2:34 PM CDT" in green directly under the Refresh button. Falls back to "Never refreshed" before first run.
Row 57 — Giving FAQ Text blue → black. Cream-bg FAQ Accordion module had its text_color_scheme set to powder-blue. Switched to black to match Mike's spec.
Status: Soft-launch sprint continues. Row 59 is the only blocker; awaiting Taylor/Austin reply on the GHL token scope. WIP commit 6c6d134 preserves three new modules (feature_cards, featured_stories, two_column_heading) plus their atom registrations — pre-session work that was dirty in the tree, not authored or reviewed in this session. Suspicious bit: the auto-sync acf-json→DB block was moved from inc/acfe-compat.php back into inc/seed-icb-flourishing.php, opposite of the prior 04-27 cleanup; flagged for second look. Site is otherwise pre-ship clean.
2026-04-27 — Soft-launch batch + Partner CTA admin fix + retina images + multi-account memory
Big session covering 11 Dev Tweaks rows (46, 53, 55, 58, 61, 62, 64, 65, 66, 67, 77, 82, 99) plus a structural fix for cross-account project memory. Four atomic commits to the theme, plus broader changes outside the repo.
Soft-launch batch (one commit per concern):
- Row 53 — Partner CTA module was rendering on the frontend but invisible in wp-admin. Cause:
partner_ctalayout was never registered ingroup_page_modules. ACF iterates layouts to know what to render in the editor; without the layout, the module data sat in the DB with no admin UI. Added the full layout (15 sub-fields: body_text, body_content, button, three image slots, bg, spacing tab, topper). Bumped the field group's modified timestamp; ranwp acf json syncon prod and local. Now visible on About + Home in wp-admin. - Row 77 — switched
@font-facefrom GT Standard M (Mid) to L (Large) cut sitewide. - Row 64 —
p a:hovernowtext-dark-orange(was navy). - Row 66 — tightened
.module-topper__middlegradient stop from 43.66% → 43% to hide the subpixel seam visible on mobile (~0.4–0.8px overlap with the SVG flat rects). - Row 65 — added
rounded-lgdirectly to each Partner CTA<img>so the corners stay rounded under iOS Safari's overflow-with-transform quirk on thefade-scale-upwrapper. - Row 67 — replaced raw
<img src="...">tags across 7 module files withwp_get_attachment_image()calls so WordPress emits its fullsrcset/sizesattributes; hi-DPI displays now actually use the 2x sources BR uploaded. Modules touched: feature_cards, featured_block, hero_media, image_text_cta, impact_grid, topic_cards, partner_cta. Going forward, new modules should usewp_get_attachment_image()not raw<img>tags — see the new note in CLAUDE.md. - Row 46 — Bio List role/title was using
$role_color(=$tc['sub_class'], the dimmed "sub" class for hero subheadings, ~60% opacity). Switched to$text_colorso titles read solid black. - Row 55 — Give address leading too loose. Collapsed consecutive
<br>runs from ACF'snew_lines=brto a single break and addedleading-snug. - Row 58 — removed
fade-upfrom footer credits row. The bottom-of-page scroll trigger fired late and made the copyright/Terms/Privacy line look missing on first reach. - Row 61 — added
space-y-10 lg:space-y-14wrapper arounddetail_rowscontent_blocks so consecutive Column Lists (e.g. VSP "having an impact") have proper margin between them. - Row 62 — centered the goals_stats divider line in the column gutter via
-left-10(matchesgap-x-20/2). - Row 82 — VSP video thumbnail caption was
whitespace-nowrapand absolute-positioned. Removed nowrap, dropped the absolute, made the caption a flex child below the play button withtext-center max-w-[calc(100%-1.5rem)]and responsive font (16px / 18px lg). - Row 99 —
column_listfilter atinc/modules/page_modules/detail_rows_blocks/column_list.php:15was dropping any column without a title. Broadened to title OR content OR icon, and wrapped the heading row in a conditional so empty titles don't leave orphan h4.
Multi-account memory architecture (outside the theme):
Eric runs two Claude Code accounts on this machine — claude (G&M, ~/.claude/) and claude-royal (HeyRoyal Max, ~/.claude-royal/, set via CLAUDE_CONFIG_DIR). Today's session ran under Royal and silently saved memories to the wrong path (~/.claude-royal/projects/...), isolated from the canonical 18 project memories at ~/.claude/projects/.... Bug discovered when Royal-side Claude couldn't load existing project context.
Existing infrastructure already had ~/.claude-shared/ for MCP server propagation, plus claude / claude-royal zsh wrappers and an iTerm tab tinter. Extended the same pattern: replaced ~/.claude-royal/{projects, agents, commands, plans, people, project-notes, hooks, CLAUDE.md} with symlinks pointing at the canonical ~/.claude/ paths. Per-account isolation preserved for .claude.json (auth + telemetry), settings.json, history, todos, and runtime caches.
New skill: ~/.claude/skills/multi-account/SKILL.md — runbook with diagnostics, failure modes (auth collision, MCP gone silent, CLAUDE.md mismatch), recovery commands, and instructions for adding a third account. ~/.claude-shared/README.md extended with a "Content sharing across accounts" section.
Also created ~/.claude/people/ (team.md for the four-person G&M team + clients/within-reach.md) so initials in any sheet/comment/Slack thread can be resolved cross-project.
Pre-ship housekeeping (late session, commit 7158e89): with Within Reach prepping to hand off to client, ran a full audit pass — PHP lint clean across the theme, WP debug log silent, Chrome console clean on Home/About/Our Partners/Flourishing Neighborhoods/O,NE/FAQs/State of the City. Cleanup applied: stripped 5 one-shot dev/seed require_once lines from functions.php (the auto-sync hook moved from inc/seed-icb-flourishing.php → inc/acfe-compat.php, scripts kept on disk as re-runnable via wp eval-file), gated inc/dev/lan-host.php to wp_get_environment_type() === 'local', deleted three orphan module templates with no ACF layout (feature_cards, featured_stories, two_column_heading) and pruned their references from inc/acf/atoms/background_color.php config examples + inc/dev/normalize-module-spacing.php map. Net 8 files / -312 lines.
Skills architecture refactor (Royal ~/.claude-royal/skills/): addressed a voice/tone duplication problem — Slack brevity rules I added inline today already overlapped with /chatty. Rebuilt the comms layer: /chatty is now the single source of truth for how Eric writes anywhere, channel skills (/slack, /email, /basecamp) own only mechanics (mention syntax, length budget, API plumbing) and each opens with a "Read First — Voice Lives in /chatty" header. Spawned skills-doctor agent for cross-pollination; surfaced three other drafting skills missing the /chatty reference (/soft-launch, /maintenance, /git for commit message bodies) — wired all three. Plus reciprocal "Related Skills" links between /slack-formatting ↔ /slack-app-dev, and /laymans-terms ↔ /chatty (clarifying that laymans-terms is an adapter on top, not a replacement). Committed as one atomic commit in the royal skills repo.
Status: Soft-launch sprint continues. Open ED-assigned Dev Tweaks remaining: Row 46 (Bio List title at 60% — BR follow-up after my prior fix) and Row 53 (BR clarified the missing module is a 3-photo block, not Featured Block — still needs investigation). Row 63 is just Mike's "🔥" compliment (stamp-only). Row 68 (Footer Form submit confirmation) is blocked on client decision. Site is otherwise pre-ship clean.
2026-04-24 — Bug-fix sprint, search expansion, spacing audit, polish features
Long focused session — 16+ commits across 13 distinct concerns. No new modules; everything was refinement, hygiene, or small features.
New features:
- Upcoming Events nav dropdown — third dropdown layout (
events) on the primary nav repeater. Auto-pulls 3 upcoming events viatribe_get_events(), renders a 3-up portrait card grid with the green date badge fromloop-event-row.php, "View all events" link in serif. Renders in both desktop dropdown and mobile accordion. Editor flips a nav item to dropdown + Upcoming Events (auto). Files:header.php,inc/partials/nav-events-cards.php,acf-json/group_theme_settings_nav_announcement.json. - Announcement bar marquee — long-text scroller pattern using duplicate-content + translateX(0 → -50%) for seamless loop. JS detects overflow + sets duration; pauses on hover/focus; honors
prefers-reduced-motion. Saved to/ui-kitskill for reuse on future sites. - Search overlay GSAP timeline — open: backdrop fade + panel scale, close: snappier reverse, prefers-reduced-motion fallback.
- On-brand
::selection— orange + black, WCAG AAA. - Hero Media
button_icon_typepicker — None / PDF / FA selector (other agent's work).
Search index expansion (Phase 2 of QA pass):
- Fixed real bug in
wr_expand_search_to_index()— regex was injecting EXISTS clause into the password-check group (always-true), so the search-text index was inert. Replaced regex-splice with full search-clause rebuild. - Added
tribe_eventsandfaqtowr_search_indexed_post_types()+ backfilled. - Added
pre_get_postshook to force-include indexed types in main search query (overridesexclude_from_search=trueon FAQ/events). - Verified: searching "Jed" → /about/, "denomination" → FAQ, "registration" → event. Bogus queries still return nothing.
- Single clear-X button in search input — fixed duplicate-ID bug between Cmd+K overlay and search.php inline form. Native WebKit clear button suppressed via CSS.
Module spacing audit (Phases 1-4):
- Inherited Phase 1-3 from another agent (
inc/dev/audit-module-spacing.php,docs/MODULE-SPACING-DEFAULTS.md). - Wrote Phase 4 normalizer (
inc/dev/normalize-module-spacing.php) — default dry-run, applies viaWR_DRY_RUN=0or?live=1. - Two-pass design: Phase A clears orphan fields on every module (data hygiene, no exclusions); Phase B normalizes values (respects per-page and per-pair exclusions per the proposal).
- Applied 21 value normalizations across 12 pages; reverted 9 after page-by-page review (5 detail_rows ADDED, 3 featured_block FLATTENs, 1 faq_accordion BIG JUMP).
- Cleared 73 orphan fields across all 21 pages with any drift (including Home, which is excluded from value normalization).
- Verified:
wr_module_spacing()only consults active fields per spacing_type, so cleared orphans are inert at render. Sample pages render unchanged.
ACF normalization:
- Found PHP 8
_namewarnings firing on every page render (hundreds per request), specifically on search results pages. - Root cause:
wr_acf_atom_text_color_scheme()returned a field array without_name, and the auto-injection filter spliced it into every Flexible Content layout's sub_fields. - One-line fix in the atom (
'_name' => 'text_color_scheme'). - Defensive: also normalized 396 sub_fields + 28 layouts across 8 ACF JSON files to add
_namemirroringname(canonical ACF format).
Layout fixes:
- Partner CTA (About) — long text was bleeding into bottom-image collage. Constrained text to row 1, anchored large image bottom via
lg:self-end, bumped row gap. - Stats Quote Grid — image_2 stretches to fill right column on desktop (
flex-1/min-h-0/aspect-autoat lg+). - Hero Media text-block — fluid
clamp(500px,60vw,800px)width replaces stair-step col-span breakpoints; smooth scaling 1024 → 1920px. - Hero Media side image (State of the City) — pulled out of grid, absolute-positioned with explicit anchors derived from Figma (top: header + 7rem; max-h: 90vh - header - 17rem). No header collision; rounded corners visible on the actual image element.
- Header nav —
whitespace-nowrapon every link/button so multi-word labels can't break to two lines; tightened gap (gap-4 xl:gap-9).
Other:
- Mobile menu polish — close button overlap, tap-highlight removal, scroll-shadow indicator, single-toggle hamburger, viewport-fitted overlay, pinned footer with CTA + socials.
- Module animations rollout —
fade-up+data-delayon 9 modules + mobile menu open/close timeline + story templates. - 404 page — redesigned as mini-sitemap.
- Topic Cards — only apply
hover-zoomwhen card has a link.
Memory notes saved (cross-session):
feedback_session_start_dirty_tree.md— at session start, surface pre-existing uncommitted work, never silently ignore.feedback_todoist_complete_section.md— for this project, move tasks to "Complete" section (id6gRjq7Pc5PPXmJq2) instead of closing them. Eric wants completed work visible on the kanban.
Status: Core build complete; bug-fix and refinement phase. Next likely focus: any remaining Mike-gated decisions on spacing (goals_stats → detail_rows pair, Home page rhythm), continued soft-launch tweaks.
2026-04-17 — ACF architecture hardening
Unified the Topper field admin UI across every page module — editors now see identical labels, instructions, and field order regardless of which module they're in. Rolled out the Field Atom pattern (inc/acf/atoms/) as a PHP-level alternative to ACF Clone so shared field schemas can't drift. Migrated hero_page, faq_accordion, and partner_directory to atoms. Normalized 28 ACF JSON files in one sweep (new inc/dev/normalize-topper-fields.php — one-shot, since deleted).
ACF safety work:
save_jsonkill switch ininc/acfe-compat.php— ACF's auto-JSON-save feature silently wiped 26 source-of-truth JSON files during a bad sync today. Disabled permanently. JSON is now the authoritative store; DB is a cache. See CLAUDE.md's ACF Architecture section.- DB repair tooling —
inc/dev/repair-acf-db.phpcleans bloated field groups (from clone-expansion bugs) while preserving page content.inc/dev/verify-acf-state.phpis a read-only diagnostic. - Global
/wordpress-acfskill created — captures all the lessons (never passacf_get_fields()toacf_import_field_group(), always disable save_json before programmatic imports, the canonical safe sync recipe).
Status: ACF architecture is stable. Topper field renders consistently across all modules. Field Atoms pattern documented in both the theme CLAUDE.md and the global /wordpress-modules skill (FIELD-ATOMS.md reference file).
2026-04-13 — Project setup + GHL API request
Set up project tracking: Todoist dev project, linked Harvest, confirmed masterdoc, added to sites.json. Created /project-notes skill for standardized project hub management.
Emailed Austin Hall at threesixty° requesting GHL Private Integration Token and Location ID confirmation for Within Reach sub-account. Need these to build the form embed module (dropdown selector instead of paste-in embed codes).
2026-04-14 — Forms 360 integration built
Austin sent the PIT. Tested GHL API (33 forms returned), confirmed form schema endpoint is not supported (GET /forms/{id} → 401), so native-render approach abandoned. All forms use iframe + auto-resize.
Built form_embed ACF Flexible Content module. Dropdown populated dynamically from GHL /forms/ endpoint, cached 24hr, manual refresh button at Theme Settings → Integrations. Module live on /contact/ page for testing.
Full architecture docs: theme/docs/INTEGRATIONS-FORMS-360.md.
Status: Active — form embed module ready; next steps are wiring into Partners (Join Us tab), Give, and Love Our Schools Day pages as designs come online.
2026-04-14 — Module system expansion + Give/About buildout
Major day. Three initiative pages (Churches & Leaders, Flourishing Neighborhoods, Village School Partnerships) populated with full Figma content end-to-end. Give page hero + Stats Quote Grid + Partner CTA live. About page extended with the "future of our city" partner_cta (moved from Give) + topper divider.
Module system work:
detail_rowsrefactor — row content now lives in a nestedcontent_blocksflex field. Each row stacks self-contained block types (currentlydescription+facts_grid) instead of bolting on conditional-logic fields per variant. Adding a new variant = one JSON layout + one PHP partial. Seetheme/docs/MODULE-DETAIL-ROWS.md.- New modules:
image_callout_banner,goals_stats,stats_quote_grid(2×2 mosaic with image/stats/quote/image cells at exact Figma aspect ratios). - Partner CTA enhancement — added optional
body_contentWYSIWYG with scoped.prose--partner-ctastyling (powder-blue on navy bg, black on light). Lets editors add a lede + bullet list with bold lead-ins without touching HTML. - Spacing tab coverage — every module now exposes identical Spacing controls (Type / uniform / Top / Bottom / Topper radio). Unified
show_topper+topper_overlaybooleans into a singletopper_styleradio (none/standard/overlay) with explicit per-option guidance. 14 older modules were missing thespacing_typeradio entirely; all filled in. - Spacing Rhythm guide —
theme/docs/SPACING-RHYTHM.mddocuments the transition math (A.pb + B.pt), site patterns, and an audit workflow so "make this page feel consistent" is a measurable pass, not a vibe check.
Surprise lessons baked into memory:
- ACF's get_field → update_field round-trip on page_modules can silently drop cloned-module fields (notably hero_media text content); prefer direct per-key update_post_meta or surgical SQL for row edits on pages that use the serialized flex storage mode.
- Never mass-UPDATE spacing_type meta without CDP-measuring at least 3 reference pages before and after — did it once today, clobbered editor intent, had to recover.
Status: Active — initiative pages + Give + About top half complete. Next: About page completion, Partners page, remaining program pages as designs land.
2026-04-14 PM — About page hero + module spacing pass
About page hero (page ID 58) populated from Figma node 7819:18255 — image sourced from Drive (within-reach-about.jpg), eyebrow + headline set on existing hero_media module. Image lives at theme/assets/images/within-reach-about.jpg and as media library attachment ID 964.
Module spacing pass:
- text_block: added Spacing tab (matches detail_rows pattern), made heading mb-6 and grid render conditional on populated columns so empty repeater rows don't leak bottom space.
- detail_rows: rows now first:pt-0 last:pb-0 so module-level py- isn't doubled up; intro heading mb-16 to preserve heading→first row gap. Default bg flipped to cream.
- image_callout_banner: min-h corrected to 450px (was 445).
- Topper data wiped site-wide (29 rows of show_topper/topper_overlay flipped to 0). Re-enable per-module if needed.
Admin polish:
- Cmd/Ctrl+S save shortcut on post edit + ACF options pages (no plugin).
- Default content editor hidden on initiative post type (was already hidden on page).
Status: Active — About page next: wire up the rest of the modules from the Figma designs (~18 artboards remaining).
2026-04-14 EOD — Hero video popup + Featured Block split + About CTA migration
Featured Block redesign. Added image_position (Left/Right) and enforced a 55/45 grid with the image column always larger. Image rendered via pb-[100%] + object-cover so any upload crops to a square. About page "Join the Movement" CTA (page 58, module 4) migrated from partner_cta → featured_block with data carried over (body_text→heading, body_content→content, button, image_large→image). Reverted the first partner_cta instance (module 1) to its original 3-image collage after the template change briefly affected both instances.
Hero Media video popup. Added optional bottom-right video trigger (show_video_popup, video_thumbnail, video_url) + a Buttons repeater (up to 3 side-by-side). Opens via GLightbox — supports Vimeo, YouTube, and self-hosted MP4. Global GLightbox init moved from single-story.php into assets/js/main.js so .glightbox-single works anywhere on the site.
Hover zoom pattern (reusable). Ported California Forever's .video-card GSAP hover (image scale 1.08 with power3.out, play-button back-out bounce, orange pulse ring). Lives in initVideoCardHover() in assets/js/gsap-animations.js. inc/partials/video-thumbnail.php now emits .video-card / .video-card-bg / .video-card-play / .video-card-pulse automatically.
Programs / O,NE single populated. /programs/one/ hero wired up with Drive assets: within-reach-one.jpg as background, within-reach-one-1.jpg as video thumbnail, O,NE-Hero.mp4 self-hosted as the popup source. Content + 2 buttons (Register / Follow on Instagram) match Figma node 7843:18468.
Status: Active — ready for the next round of Figma artboards.
2026-04-15 — ACF schema drift cleanup + Mental Health Care buildout + Forms 360 picker atom
ACF schema drift diagnosed and fixed. The April 14 detail_rows refactor updated the PHP + DB structure but left the ACF field definitions on the old schema. Admin showed empty fields while content lived in postmeta; admin saves were silently dropping modules that had no layout definition registered. Root causes and fixes:
- Detail Rows — replaced the old rows-repeater sub_fields (badge/description/button) in
group_page_modules.jsonwith the new schema:badge_styleradio, conditional badge + badge_color, title, image,content_blocksflexible_content (description + facts_grid layouts with groups repeater), button. The frontend loader now readscontent_blockslayout names from the parent array (unserialized by get_post_meta) and falls back to the per-index_acf_fc_layoutonly when missing, making admin reorders non-destructive. - Description block partial — wraps content in
wpautop()before kses so ACF's wpautop-on-save/wpautop-on-render round-trip doesn't strip paragraphs when read via get_post_meta. - Image Callout Banner + Goals Stats — both had PHP + post data but zero ACF layout definitions in the flex, so every admin save dropped them. Added full layouts with shared spacing + topper controls.
- Featured Block — exposed Spacing + Topper admin controls (previously only in DB via seeders) and added a
light-bluetext_color_scheme that appliestext-powder-blue+.prose--powder-blueon cream backgrounds. - Text Block — made columns/content optional (removed min=1 on columns, required=1 on column_content); narrow
max_widthnow wraps content in an innermax-w-3xldiv INSIDE.contentso the container's viewport padding is preserved, left/center-aligned to matchtext_align. - Stats Quote Grid — added the full layout to the flex field (was PHP-only).
Forms 360 picker atom. Extracted the GoHighLevel form dropdown as a convention-based ACF atom: any select field named form_id with 'wr_ghl_picker' => true auto-populates via acf/prepare_field/name=form_id in inc/integrations/ghl.php. Pairs with the existing wr_render_ghl_form_iframe() helper. wr_page_has_form_embed() renamed to wr_page_has_ghl_form() (back-compat alias kept) and widened to detect form usage on any module. Featured Block gets a new content_type radio (image/form) — when form, the image column renders the Forms 360 iframe in a white rounded container instead of the square image.
Mental Health Care page populated. 7 modules: hero_media (Love Our Schools Day), text_block (large statement, narrow/left), upcoming_events, featured_block (State of the City), detail_rows (About), stats_quote_grid (30/335 stats + Danielle Brandt testimonial), featured_block form mode (Ready to make an impact? + Love Our Schools Day 2025 interest form).
Flourishing Neighborhoods page restored. A corrupted admin save earlier in the session had scrambled modules 2-5 and dropped image_callout_banner + goals_stats from the array. Rebuilt from known-good state (6 modules: hero, text_block, image_callout_banner, goals_stats, detail_rows, featured_block).
Component vocabulary documented. Added a sidebar to the planning file at ~/.claude/plans/sleepy-questing-quokka.md describing the tokens / atoms / molecules / organisms / templates hierarchy as applied to this theme, plus a "Rule of Three" extraction philosophy and a preferred-reuse-mechanisms ordering (PHP helpers > partials > field conventions > Tailwind component classes > AVOID ACF clone field groups). The schema drift lesson is formalized as memory feedback_acf_schema_drift.md — shorthand "the schema drift issue" triggers the diagnostic workflow.
Status: Active — Mental Health Care buildout complete; architecture stabilized after the detail_rows refactor fallout.
2026-04-17 — State of the City + Partners build; module system expansion; workflow hygiene
State of the City page (ID 111). hero_media extended with a side_image slot and per-button icons so the page can render the book cover plus "Purchase the Book" / "Read Sample" buttons alongside the hero text. Created two_column_heading module for the h2-left / h4-right intro pattern. Renamed initiative_cards → feature_cards (zero existing usage so no DB migration; dropped the CPT-linked initiative field for a generic ACF link field; card title is now required). Placed the Listening + Initiatives variants on the page; 8 card images downloaded from the Within Reach Drive folder, compressed, imported, and wired via WP-CLI.
Partners page (ID 61). Built numbered_callouts module ("3 Key Ways to Partner" powder-blue panel with N numbered columns). Extended detail_rows with two new content_blocks layouts: image_card (tall image + gradient overlay + bottom-left title/subtitle + optional orange arrow CTA when link is set) and column_list (1–3 side-by-side columns, each with optional icon + title + WYSIWYG body). Populated "Why Partner With Us" (image_card + descriptions) and "Partnership Levels" (column_list with Core/Champion) via WP-CLI. page.php Partners fork removed — every page, including Partners and its children, now runs through the standard page_modules.php loop. inc/partials/partners-layout.php deleted.
Icons became uploadable (not FA classes). column_list icon field flipped from text (FA class) to ACF image. New inc/svg-support.php enables SVG uploads with a lightweight sanitizer (strips <script>, <foreignObject>, inline on*= handlers, and javascript: URIs on upload) plus a viewBox-aware filter so WordPress emits sensible width/height attrs instead of 1×1. Clients can upload PNG or SVG; SVG scales crisply.
text_block picked up full Spacing tab (topper + spacing_type + spacing + top/bottom + topper_style — previously missing, consistent with every other module now). On navy backgrounds the heading flips to text-powder-blue (was text-white) to match the site's navy+powder-blue accent pattern.
ACFE copy/paste enabled. acfe_flexible_add_actions: ["copy"] on both the top-level page_modules flex and the nested content_blocks flex inside detail_rows. Admin now shows Copy/Paste actions in the top-right of each layout — clients can copy a module on page A and paste it on page B. Global acf-extended skill updated with a "Copy/Paste between layouts" section and a parallel-session hygiene note specific to acf-json/ race conditions.
Parallel-session incident (recovery workflow documented). Mid-session, acf-json/group_page_modules.json disappeared — caused by three concurrent claude --dangerously-skip-permissions sessions racing on the file. DB was intact so the JSON was regenerated via acf_prepare_field_group_for_export() + file_put_contents() (regenerated file is ~15% larger because clone references flatten to full definitions — functionally identical). Workflow improvements: new /worktree skill in the global skill library documenting three-layer defense (hygiene rules, claude-safe wrapper, worktrees); ~/bin/claude-safe shell wrapper that detects concurrent sessions at launch and offers to spawn a sidecar worktree; aliased claude=claude-safe globally in ~/.zshrc. Global acf-extended skill now documents why acf-json/ specifically is a race target and the DB→JSON recovery snippet.
Status: Active — core module system stable and documented; State of the City + Partners pages content-populated; parallel-session workflow has a safety net going forward. Next: remaining Figma pages + any soft-launch iterations.
2026-04-23 — GSAP animation system foundation
New reusable primitives added to gsap-animations.js + FOUC CSS in tailwind-source.css: .zoom-in-on-load (scale 1.1 → 1 on DOMContentLoaded, no ScrollTrigger — Safari-safe alternative to scrub-based Ken Burns), .fade-scale-up (scale 0.92 → 1 + fade, data-delay aware, scroll-triggered with once: true). Existing .fade-up enhanced with data-delay attribute support for sequenced entrances. All three share the same safe implementation pattern (see gotcha below).
Home page applications (first pass, reviewed and approved):
- hero_media — background video/image wrapped in .zoom-in-on-load for the slow settle-in; heading/eyebrow/subtext container gets .fade-up data-delay="0.2"; buttons container 0.4; scroll arrow 0.6. Staged entrance without Ken Burns stutter on Safari.
- partner_cta — text column .fade-up; large image + small image + medium image get .fade-scale-up with data-delay="0" / "0.15" / "0.3". Creates a natural top-left → top-right → bottom reading-order stagger.
Desktop nav dropdown animation (Bucket 2 — general interaction): replaced instant .hidden toggle with a GSAP timeline. Open: panel fades+slides down (opacity 0→1, y -6→0, 0.3s power3.out), then 13 items stagger in (0.03s apart, 0.25s power2.out). Close: panel reverses (0.18s power2.in), onComplete re-applies .hidden and clears inline styles. Previous timeline killed on re-trigger so rapid hover on/off doesn't jank. Falls back to instant toggle if GSAP unavailable. inc/styles-scripts.php reordered so main.js depends on gsap.
Nav click targets fixed: primary nav <a> links, dropdown triggers, and the search button were only clickable on their text. Made the whole nav-bar height clickable by adding items-stretch on the <nav> and h-full flex items-center / flex on children. Standard UX expectation now met.
Critical GSAP gotcha found, diagnosed, and documented globally. The first implementation used gsap.fromTo(...) + scrollTrigger + delay, which caused below-fold elements to self-play on page load regardless of trigger state — when the user finally scrolled down, the element flashed visible → snap to from-state → animated back in. Root cause: GSAP's immediateRender: true default on fromTo, combined with a non-zero delay, treats the delay as "time since creation" instead of "time after trigger fires." Fix: switched to the safe pattern — gsap.set() for the from-state + ScrollTrigger.create({ onEnter: () => gsap.to(...) }). Also hardened the 3s stuck-element fallback so it skips below-fold elements. Both the bug and the safe pattern are now documented in the global /gsap-animations skill under a new "Known Issue" section alongside the iOS Safari scroll jank note.
Skill taxonomy formalized. Added "Animation Taxonomy: Two Buckets" section to the global /gsap-animations skill defining Bucket 1 (scroll entrances, class-driven, automatic) vs Bucket 2 (general interactions, recipe-driven, user-initiated). Every future theme inherits this framing.
Status: Foundation in place. Walkthrough paused at module 3 (stat_callout) — will resume after Eric reviews the first two modules. Remaining home-page modules to animate: stat_callout, topic_cards (x2), featured_stories, impact_grid, upcoming_events, partner_cta (module 9). A within-reach project override for /gsap-animations is queued to capture the site's motion philosophy and module-to-animation map once the full home page is decided.
Quick Reference
- Build instructions: Within-Reach-Claude-Build-Instructions.md
- Wireframes: Wireframe_pages/ (19 pages)
- Figma designs reviewed (V3 page, 19 artboards — most current source of truth)
- Figma node IDs: figma-node-ids.md
- Google Drive assets: google-drive-assets.md — full inventory of all site images (62 images, 14 folders)
- Flowchart: NOT YET RECEIVED (image was too large in prior session)
Site Architecture
Navigation Structure (from updated mockup)
Top bar: Optional news statement banner — navy background, orange text, dismissible (X). Managed via ACF options page.
Primary Nav: Floating white bar with rounded corners over hero. Logo left, nav center, Give CTA right.
| Item | Type | Notes |
|---|---|---|
| What We Do | Mega dropdown | 3 columns: Initiatives, Programs, Resources |
| Upcoming Events | Link | → /events |
| Partners | Link | → /partners |
| Stories | Link | → /stories |
| About | Link | → /about |
| Give | CTA button (orange/gold) | → /give |
Mega Dropdown — What We Do (CONFIRMED):
| Initiatives | Programs | Resources |
|---|---|---|
| Flourishing Churches & Leaders | Citywide Summit | State of the City |
| Flourishing Neighborhoods | City Serve | For the Good |
| Village School Partnerships | O,NE | |
| Mental Health Care | For the Good |
Note: "For the Good" appears in both Programs AND Resources columns.
Footer: Full sitemap links, email signup ("Stay in the know"), social icons (Instagram, Facebook, YouTube), copyright, Terms / Privacy / Web Accessibility links
Pages Inventory
Core Pages (ACF Flexible Content)
| Page | Wireframe | Key Sections |
|---|---|---|
| Homepage | Home.png | Hero, intro text, initiatives grid (4), programs row (4), stats bar, testimonial quote, upcoming events (2), partner CTA, recent stories (3), Give bar |
| About | About.png | Hero text, mission statement, stats grid (6), team bios (3+), "Join the Movement" CTA w/ checklist |
| Give | Give.png | Hero w/ dual CTAs (Give Now / Partner), stats + quote, "Partner with Us" section, Giving FAQs (accordion) |
| State of the City | State of the City.png | Hero w/ book CTA, large pull quote, listening project details (numbered list), "Moving Toward a Better Future" section |
| Partners | Partners.png + Partners-1/2/3.png | 4-tab layout (Partner With Us, Our Partners, Join Us, FAQs) |
Partners Sub-Views (Tabbed Interface)
| Tab | Wireframe | Content |
|---|---|---|
| Our Partners | Partners.png | Filterable sidebar (Category, City), partner list by tier (Champions, Core), "Join the Movement" CTA |
| Partner With Us | Partners-1.png | Why partner, how to partner, partnership levels (Partner vs Champion), how support is used, Join the Movement |
| Join Us | Partners-2.png | Join form (Church/Org name, Name, Role dropdown, Email, Phone, Address, Website, Staff list) |
| FAQs | Partners-3.png | Accordion FAQ list (10+ questions) |
Initiative Pages (Custom Post Type: initiative)
| Initiative | Wireframe | Key Sections |
|---|---|---|
| Flourishing Churches & Leaders | Flourishing Churches & Leaders.png | Hero, Leadership Gatherings, Leadership Cohorts (launching 2026), Development Environments, State of the City callout |
| Flourishing Neighborhoods | Flourishing Neighborhoods.png | Hero, mission statement, Our Goals, For the Good Book section, State of the City callout |
| Village School Partnerships / Serve Our Local Schools | School Partnerships.png + Serve Our Local Schools.png | Hero, mission block, How it Works, Love Our Schools Day callout, State of the City callout. Note: "Serve Our Local Schools" wireframe IS this initiative (per Eric — wireframe label "Program" is incorrect). |
| Mental Health Care | Mental Health.png | Hero, stats (3), Training Leaders, Expanding Access, Developing Counselors, Resources, State of the City callout |
Program Pages (Custom Post Type: program)
| Program | Figma Node | Key Sections |
|---|---|---|
| O,NE | 7247:12454 | "Programs" breadcrumb. Full-bleed hero (crowd photo), title + subtitle + Register CTA, mission text, photo grid + stats (5,000 students / 75+ schools), testimonial w/ quote + photo, Support O,NE CTA w/ image |
| Citywide Summit | — | No design yet — confirmed as a Program CPT entry |
| City Serve | — | No design yet — confirmed as a Program CPT entry |
| For the Good | — | Annual event only — managed in TEC, not a Program CPT entry. Nav links point to the event. |
Resource Pages
| Resource | Figma Node | Key Sections |
|---|---|---|
| State of the City | 7248:12903 | Labeled "Resources" in breadcrumb. Hero w/ book cover + Purchase CTA, full-bleed pull quote, Comprehensive Listening Project (4 numbered items), Moving Toward a Better Future, State of the City callout |
Content Type Pages (updated from Figma designs)
| Page | Figma Node | Key Sections |
|---|---|---|
| Stories Archive | 7260:14623 | No category filters in design (wireframe pills removed). Intro text, masonry-ish card grid (image + title + excerpt + orange arrow), no pagination visible — may load more or be limited |
| Individual Story | 7260:14869 | "Stories" breadcrumb label, title + subtitle, hero image w/ video play button, body content, large pull quote, body content continued, share row (X, LinkedIn, Facebook, email), Recent Stories (2 cards) |
| Events Archive | 7241:7053 | No category filter or search in design (wireframe filters removed). Simple list: date badge (orange) + event name + type label + description + image. "For the Good" listed as an event here. |
| Individual Event | 7241:7533 | "Events" breadcrumb, title, Register button (orange), date/time/location, Add to Calendar + share icons, body content, Register button again, Upcoming section w/ "See All Events" link |
Content Types Summary
| Type | Post Type | Archive | Notes |
|---|---|---|---|
| Initiatives | initiative (CPT) |
/initiatives | Evergreen pillar pages, modular ACF. 4 entries. |
| Programs | program (CPT) |
/programs | Program pages, modular ACF. 3-4 entries. |
| Stories | story (CPT) |
/stories | Editorial, chronological, no categories, no tags, no author display |
| Events | tribe_events (TEC Pro) |
/events | Template overrides only, preserve plugin functionality |
| Partners | partner (CPT) |
— | Partner organizations. Fields: name, tier, city, category. Used on Partners page. |
| Pages | page |
— | ACF Flexible Content (Home, About, Give, State of the City, Partners) |
ACF Modules Identified (updated from Figma designs)
| Module | Used On | Design Notes |
|---|---|---|
| Hero (full-bleed photo + text overlay + CTA) | Home, About, Give, Initiatives, Programs, State of the City | Dark overlay on photo, white/light text, orange CTA buttons |
| Stats Bar / Grid | Home, About, O,NE, Mental Health, Love Our Schools Day, Give | Orange background with white text. Variable column count (2-6). |
| Testimonial / Pull Quote | Home, O,NE, Mental Health, Love Our Schools Day, Give, Stories single | Dark navy background, large quote text, photo beside quote |
| Initiative Grid (4-up image cards) | Home | Image cards with text overlay, orange arrow CTAs |
| Programs Row (4-up image cards) | Home | Similar to initiative grid |
| Recent Stories Feed | Home, Individual Story | Image cards with title + excerpt overlay, orange circle arrow |
| Upcoming Events Feed | Home, Individual Event, Love Our Schools Day | Date badge (orange) + event title + type + description |
| Content + CTA Block | Home, About, Give, Initiatives | Text with orange CTA button |
| Team Bios Grid | About | Photo + name + title + bio text + email link |
| Join the Movement CTA | About, Partners (all tabs) | Dark navy photo background, checklist (Equipping, Collaborating, Extending), "Join the Movement" button |
| Tabbed Content | Partners (4 tabs) | Left sidebar tabs: Partner With Us, Our Partners, Join Us, FAQs |
| FAQ Accordion | Give, Partners | Question headers with expandable answers |
| GHL Form Embed | Partners (Join Us), Love Our Schools Day | GoHighLevel form embed |
| Video Embed | Stories single | Orange play button overlay on image |
| Share Row | Stories single, Individual Event | X, LinkedIn, Facebook, email icons |
| Partner List (tiered) | Partners (Our Partners) | Champions and Core tiers, filterable sidebar |
| State of the City Callout | All 4 Initiative pages | Book cover image + text + "Learn More" CTA. Consistent across all initiatives. |
| Image + Text (side by side) | O,NE, Love Our Schools Day, Initiatives, Partners | Photo left or right, text opposite |
| Partner CTA Block | Home | Orange icon mosaic + text + "See Initiatives" or "Partner With Us" CTA |
| Give + Email Signup Footer | GLOBAL — every page | Gold map graphic "Give" block + "Stay in the know" email signup + orange "Send it" button |
| Full Sitemap Footer | GLOBAL — every page | Dark navy, logo, contact info, social icons, 4-column nav (Events/Partners/Stories/About, Initiatives, Programs, Resources), copyright + Terms/Privacy/Web Accessibility |
Recurring Patterns (confirmed from designs)
- State of the City callout — identical block on ALL 4 Initiative pages: book cover + "Learn More" CTA. Build as a reusable module or global ACF content block.
- "Join the Movement" CTA — dark navy photo block with Equipping/Collaborating/Extending checklist. Used on About + all 4 Partners tab views. Single reusable module.
- Give + Email Signup footer — appears on EVERY page. Gold map "Give" block + "Stay in the know" + "Send it" button. Build as a global footer element (not per-page module).
- Full sitemap footer — dark navy, consistent across all pages. Global element.
- Stats bars — orange background, white text, variable count (2, 3, 6). Single flexible module.
- Partner tiers (Champions, Core) — taxonomy on the Partner CPT.
- Orange as the primary accent color — CTAs, buttons, stats backgrounds, date badges, play buttons all use the same orange/gold.
- Dark navy as the secondary color — footer, Join the Movement CTA, section backgrounds.
- "For the Good" is multi-purpose — listed as both a Program, a Resource, AND an event. Likely an annual event that also has a dedicated program/resource page.
Forms Strategy — GoHighLevel (gothreesixty.io)
No WordPress forms plugin. The client uses GoHighLevel (white-labeled as gothreesixty.io) for all forms. Form data is stored in GHL's database, not WordPress.
Integration approach:
- GHL form embed URL structure: https://msgsndr.com/widget/form/[FORM_ID]
- GHL provides iframe and JS embed codes from its "Integrate" tab
- WordPress plugin (LeadConnector) exists but doesn't offer a clean form-ID shortcode
- Recommended ACF module: Textarea field where client pastes the GHL embed code. We wrap it in a styled container. Client doesn't deal with raw HTML — they go to GHL → Forms → Integrate → Copy → Paste into the module.
- Alternative (cleaner UX, more fragile): Text field for just the Form ID, we construct the iframe. Only works for inline forms, breaks if GHL changes URL structure.
- Eric's preference: Avoid iframe if possible. Ideal: form ID field, clean render. We'll investigate what GHL actually supports and decide.
Forms needed: - Partner Join (Partners page, Join Us tab) - Volunteer signup (Serve Our Local Schools / City Serve) - Email signup (footer global — may be separate from GHL)
Resolved Questions
- [x] Stories categories → No categories, no tags (build doc is correct, wireframe filter pills are outdated)
- [x] City Serve vs Serve Our Local Schools → Serve Our Local Schools IS the Village School Partnerships initiative (wireframe "Program" label is incorrect)
- [x] Partner data → Custom post type (
partner) - [x] Forms plugin → GoHighLevel (gothreesixty.io, white-labeled GHL) — not Gravity Forms
- [x] News banner → ACF options page (toggle, text, link)
- [x] Search → Global site search (not just events)
- [x] Citywide Summit → Program CPT entry (needs wireframe)
- [x] Eric's categorizations override wireframe labels when they conflict
- [x] For the Good → Just an annual event in TEC. Nav links (Programs + Resources columns) point to the event. No separate program/resource page.
- [x] Event categories → No filtering in design (wireframe filters were removed)
- [x] Citywide Summit + City Serve → Same modular template as O,NE — no dedicated designs needed, scope as Program CPT entries
- [x] Email signup footer → GoHighLevel (same platform as all other forms)
- [x] All stats across the site → Client-editable via ACF (every stats module gets editable number + label fields)
- [x] Stories archive → Load more button (start with initial set, load more on click)
- [x] Nav structure → Follow the Figma mockup exactly. Don't second-guess what's in the nav.
Open Questions
- [ ] Flowchart — still needs to be uploaded (was too large in prior session)
- [ ] GoHighLevel form embed method — need to confirm whether iframe or JS snippet, and test the form ID approach vs full embed code
Plugin Stack
Required
| Plugin | Purpose | When |
|---|---|---|
| ACF Pro | Flexible Content, CPTs, custom fields, options pages | Day 1 |
| The Events Calendar Pro | Events management, /events archive, single event templates | Day 1 |
| SEO plugin (Yoast or Rank Math) | Meta tags, sitemaps, schema | Before launch |
Evaluate During Build
| Plugin | Purpose | Notes |
|---|---|---|
| LeadConnector | GoHighLevel WP plugin | Test if it helps with form embeds beyond manual embed codes |
| Safe SVG | SVG upload support | If brand assets need SVG uploads |
| Redirection | 301 redirects from old site URLs | Launch concern — existing site being replaced (no content migration, but old URLs exist) |
Not Using
| Skipping | Why |
|---|---|
| Gravity Forms | GoHighLevel handles all forms |
| Elementor / page builders | Custom theme + ACF Flexible Content |
| Gutenberg block plugins | Not using block editor for layout |
| WP Migrate | No content migration — fresh content |
Priority Objectives (from Build Doc)
- Story engagement
- Event registration
- Partner signups
- Donations
Non-Goals (from Build Doc)
- No member portal
- No dashboard
- No complex filtering systems
- No overengineered taxonomy structures
- No Elementor, no Gutenberg block sprawl
Build Plan
Phase 1: Foundation
- [ ] Create Local by Flywheel site
- [ ] Scaffold custom theme (from scratch, no starter)
- [ ] Set up Tailwind CSS
- [ ] Define design tokens (colors, typography, spacing — work with Eric from Figma)
- [ ] Register CPTs:
initiative,program,story,partner - [ ] Register taxonomies: partner tiers (Champions, Core)
- [ ] Set up ACF options page (news banner, global settings)
- [ ] Build global elements: header/nav (mega dropdown), footer (Give + email signup + sitemap)
Phase 2: ACF Modules
- [ ] Build core reusable modules (Hero, Stats, Testimonial, Content+CTA, Image+Text, FAQ Accordion, Form Embed, Share Row, etc.)
- [ ] Build specialized modules (Initiative Grid, Programs Row, Stories Feed, Events Feed, Team Bios, Partner List, Join the Movement CTA, State of the City Callout)
Phase 3: Page Templates
- [ ] Homepage
- [ ] About
- [ ] Give
- [ ] Partners (tabbed layout: Partner With Us, Our Partners, Join Us, FAQs)
- [ ] Initiative single template
- [ ] Program single template
- [ ] Story archive + single
- [ ] State of the City (Resource page)
Phase 4: Events Integration
- [ ] Install The Events Calendar Pro
- [ ] Override event archive template (styled to match design)
- [ ] Override single event template
- [ ] Style to match theme
Phase 5: Forms + Polish
- [ ] GoHighLevel form embed integration
- [ ] Global search
- [ ] SEO plugin setup
- [ ] Performance audit (lazy loading, minimal queries)
- [ ] Accessibility review
- [ ] Redirects from old site (Redirection plugin)
Notes
- Existing site is being replaced but no content migration — fresh content
- Design tokens will be defined collaboratively (not just pulled from Figma)
- Plugins (ACF Pro, TEC Pro) not licensed yet — build theme structure first, integrate when ready