Full Phase 1 scope rebuild. Mining systems mapped. Last-mile gap identified. Launch verdict: โ ๏ธ HOLDS WITH SCOPE CUT (15-18 pages) OR slip to May 8 for full 30 pages. 18-gate rehearsal: 10 PASS / 0 FAIL / 2 WARN / 6 INFO.
โ Cutover Plan v4 โ Staging Audit โ Content InventoryLive rehearsal report: 7 PASS / 0 FAIL / 4 INFO. v3 LOCKED with all 7 decisions. B2 pivot to Rank Math Redirections (Rule of One). Automated via cutover_rehearsal.py.
Live rehearsal report: 7 PASS / 0 FAIL / 4 INFO. v3 LOCKED with all 7 decisions. B2 pivot to Rank Math Redirections (Rule of One). Automated via cutover_rehearsal.py.
ct_other_template, Bricks pages use _bricks_editor_mode. They do not conflict. We migrate page by page during Phase 2 -- old pages stay on Oxygen until their Bricks replacement is QA'd and approved. At no point does a page break because both builders are installed. Once all pages are migrated, we deactivate Oxygen.The meeting included discussion of a prior incident where Russ committed BSP to a $15,000/month contract with Cumulus but only reported it as $5,000/month. The company now owes $70,000 and faces a lawsuit. Legal action against Russ would be too expensive and likely futile (he was an employee, not a contractor, and lacks assets). Stephanie compared the Oxygen platform limitations to similar difficulties experienced with Fair, Dane, and Russ -- a pattern of external dependencies creating bottlenecks. The migration to Bricks + Unbounce breaks this pattern by giving the team direct control.
Everything Audrey needs is here. Unbounce workflow, service page copy for 6 services, Google Reviews integration, and links to every brief. The copy is ready to paste. The keywords are baked in. Your design is the Single Source of Truth -- these are supplements, not replacements.
Audrey owns the design direction. Her role shifts from designing pages that get compromised by Oxygen to designing a master template system that gets replicated exactly across every page.
Unbounce is a standalone drag-and-drop landing page builder. It publishes directly to callbrightside.com via the WordPress plugin (already installed and active). Previous vendor 180 used Unbounce successfully for professional landing pages with heatmaps and A/B testing.
Figma is how Robert's terminal connects to your designs. You design, Robert's scripts extract the layout automatically and build the page. No manual rebuild. Your design goes live exactly as you made it. Figma imports .ai files from Illustrator.
Audrey wants live Google reviews in her landing pages. Instead of a third-party widget, we use the Google Places API to pull raw review data directly and inject it into Audrey's custom-designed review card layout. Reviews update automatically -- when a new Google review comes in, it shows on the landing page.
This section gives Audrey pre-written content for each service landing page. Each service has three blocks of copy: the Hero (what the customer sees first), the Problem/Solution (why they need this service), and the Trust/CTA (why BSP is the right choice). The copy is written for real customers based on BSP's three personas -- Emergency Eric (panic, needs same-day), Renovation Rachel (researching, comparing quotes), and Maintenance Mike (routine, wants no surprises). Keywords are baked in naturally so Google ranks the page without the copy feeling stuffed.
How to use: Open the service you're building. Copy the text. Paste into your Unbounce page. Adjust to match your design. The copy is a starting point -- Audrey has creative freedom to modify, but the structure and keywords should stay. Full keyword research lives at BSP Keyword Weaponization Strategy.
Sewer repair is BSP's highest-ticket service. The customer searching for this is either in panic mode (sewage backing up) or doing research after getting a scary quote from a competitor. The copy must do two things: (1) make Emergency Eric feel safe calling RIGHT NOW, and (2) give Renovation Rachel the proof she needs to pick BSP over the cheaper quote. Every paragraph should answer the question: "Why should I trust you with a $10,000 job?"
Camera inspection is the entry point for most sewer jobs. The customer Googling this is usually in research mode -- they know something is wrong but want to SEE the problem before committing to a big repair. This page must position the camera inspection as free/low-risk while building trust for the larger repair conversation that follows. 35% close rate on camera inspections to full repair.
Drain cleaning is the most common service call. The ticket is smaller ($150-$500) but it gets the technician in the door. 30% of drain cleaning calls uncover a bigger problem (cracked pipe, root intrusion, bellied line) that turns into a $3K-$15K sewer job. The copy must solve the immediate problem (clogged drain) while planting the seed that a camera inspection might reveal something bigger.
Water heater calls are almost always urgent -- the customer has no hot water and needs it fixed today. This is Emergency Eric territory. The copy must convey speed and expertise. The upsell path is from repair ($300-$800) to full replacement ($2,500-$4,000) when the unit is past its lifespan. Energy efficiency angles work for Renovation Rachel who is planning a remodel.
This is pure Emergency Eric. The customer is panicking -- pipe burst, sewage flooding the basement, water pouring from the ceiling. They are calling the first plumber who answers the phone and sounds competent. The copy must be SHORT, ACTION-ORIENTED, and phone-number-forward. Do not make this person read paragraphs. Get them to the phone number in under 3 seconds.
Trenchless is the premium option -- customers pay more because they keep their yard intact. This is Renovation Rachel territory. She has already been told she needs sewer repair and is now researching her options. The copy must explain the technology simply (pipe lining vs pipe bursting), position it as the modern alternative to digging, and justify the higher price through convenience and warranty.
This section explains why the service pages on callbrightside.com do not match Audrey's designs, and why this is a platform limitation rather than a design or development issue. Understanding this matters because every dollar we spend on Google Ads sends a customer to a page that underperforms -- the design Audrey creates and the page the customer sees are two different things because Oxygen cannot bridge the gap.
This section presents three paths forward at different investment levels. All three solve the Oxygen problem. The difference is speed and long-term scalability. You do not need to pick now -- the meeting today is to discuss these options together. But understanding the tradeoffs will help the conversation move faster.
This section lays out the full migration from Oxygen to Bricks Builder in two phases. The first phase delivers PPC landing pages within one week. The second phase migrates the entire site. At no point does the live site go down -- we build the new pages alongside the existing site and swap when ready.
Every tag, tracker, and plugin on the site operates at the WordPress level, not the theme level. Swapping Oxygen for Bricks does not touch any of them. Here is every system and why it is safe.
Data.Export JWT stored at /opt/nexus/nexus/config/.env as CLARITY_API_TOKEN. Client at /opt/nexus/titan/clarity_client.py pulls project-live-insights daily at 06:30 UTC via cron, saves timestamped JSON to /opt/nexus/nexus/data/clarity/. Rate-limit-aware (10 req/day cap enforced in code). First pull 2026-04-17 returned HTTP 200 + 9 metric categories with 0 rows โ consistent with site tag still pending install (captured by clarity_install_check.timer). Moment the tag lands, daily pulls auto-populate heatmap + dead-click + rage-click + scroll-depth data for CRO.
wp_head() and wp_footer() keeps firing. Full tag audit on staging before go-live.Every migration carries risk. Here is every risk we have identified and the specific safeguard built into the plan. The bottom line: at no point does the live site go down, and we can reverse course at any stage.
Breakdance was built by the same team that created Oxygen. They know Oxygen's problems because they created them. Breakdance is their attempt to fix it. It is a better builder than Oxygen. But the question is whether it is better than Bricks for what we specifically need: programmatic control from the terminal.
We audited the migration plan against every angle -- financial, technical, SEO, people, and competitive. Here are the questions you would eventually ask, answered now so nothing surprises us mid-migration.
Robert owns the entire technical migration. This includes installing Bricks, building the API bridge, creating master templates, stamping pages, migrating content, and verifying SEO. No action required from Stephanie or Kalen on any of this.
Kalen purchased the $599 Unlimited plan (infinite websites, lifetime updates). Here is exactly what you need from him and the microsteps to get started.
_bricks_page_content_2 and _bricks_editor_mode in REST API. This enables Claude terminal to create pages via POST.Same process we did for morpheus.callbrightside.com. One DNS record in Cloudflare, one subdomain in Hostinger.
Apr 10 plan +4 days. Phase 1 microsteps with proof.
| Microstep (per plan) | Status | Proof |
|---|---|---|
| License key from Kalen | DONE | Bricks Unlimited key 18dd681bb38101636d86001366ff7686 received Apr 10, activated on staging today |
| Hostinger subdomain "bricks" | DONE | bricks.callbrightside.com live, root /home/u227696829/domains/callbrightside.com/public_html/bricks |
| Install Bricks on staging subdomain | DONE | Theme active, license activated mid-session unblocked sanitizer hooks |
| Enable REST API bridge | DONE | Snippets 11/13/15/16 deployed exposing /bsp/v1/bricks/apply-v2, /template-create, /template-priority, /page-frame-fix routes. Persistence proven via wp_update_post + wp_slash + Cloudflare purge before+after. |
| Build Golden Template from Audrey Figma | IN PROGRESS | Header template id=34 + Footer template id=35 created with entire_website + front_page priority conditions stored. CONTENT IS MY APPROXIMATION not Audrey-faithful. Walker rebuild in flight (agent ab603...8813) reading /tmp/figma_audrey_full.json structurally + uploading remaining 52 assets. |
| Test API stamping with bash script | DONE | 102 elements stamped to page id=8 sewer-camera-inspection. Verify GET returns 102 elements / 51,320 bytes 8s post-write. Live URL https://bricks.callbrightside.com/sewer-camera-inspection/ |
| Stamp all service pages by Day 7 | PENDING | Awaiting Audrey-faithful Golden Template. Service pages backlog: Sewer Repair, Drain Cleaning, Water Heaters, Emergency, Trenchless. Stamping starts once Walker output reviewed. |
_width:"1200" _widthUnit:"px" and rendered as stacked narrow columns. v2 uses _width:{unit:"px",value:1200}, _rowGap:{unit:"px",value:24}, color as {hex:"#1D1760"}, image as {id, url, filename, size:"full"}.
/wp-content/uploads/bricks/css/post-{id}.min.css. Required because Bricks\\Assets::generate_css_files method does not exist in this Bricks version (probed false).Verification gate: Produced = template id 34 + 35 in DB with priority conditions, page id 8 with 102 elements persisted, REST infrastructure proven; Correct = independent GET confirms element counts at 8s post-write, body class wp-theme-bricks confirms theme active; Changed real data = 4 wp_postmeta rows for templates, page id 8 published, Master History +5,500 bytes across 4 sections. Front-end rendering of header/footer still pending Path A manual save.
Logged via nexus_html_logger.py at 2026-04-14T19:51:30.980701 UTC
Full Apr 14 session log injected into Master History at bsp-apr14-session-comprehensive-summary. Covers HCP 13 reports, Stephanie BU cleanup real fire, stuck Scheduled dry-run, Bricks persistence breakthrough, template trash + walker v2 in flight, Evelyn 2pm prep + recap, Audrey new asks for Emergency Plumber + WH + DC.
Logged via nexus_html_logger.py at 2026-04-14T20:31:10.191807 UTC
Both landing page briefs expanded per Audreys explicit 1:45pm request. Ready for Audrey to start visual design work.
Logged via nexus_html_logger.py at 2026-04-14T20:33:25.506705 UTC
Second creative brief shipped, queued for Audrey design + Robert Bricks build
Emergency plumber landing page creative brief built and deployed. Targets the largest single keyword gap on the BSP site: 165K/mo searches at KD 23 with no dedicated landing page (currently routes to generic /plumbing-services/).
Pipeline status:
Brief: BSP_Emergency_Plumber_Landing_Page_Brief.html
Source Figma: 6Hs3YviSaG5uCzc90XKU7Q (Audrey, Apr 14)
Conversion blocker reminder: Google Ads conversion tag AW-17179856077 has been MISSING for 14+ days. Restore before this page goes live or Smart Bidding cannot learn from the new traffic.
Logged via nexus_html_logger.py at 2026-04-14T20:34:30.183759 UTC
Scope: Re-pull Audrey's Figma (file GViYd2jKWUEpLbz1lWghby, Desktop-1 frame 1440x8162), rewrite walker to fix footer 3-col and header layout, deploy via REST.
What shipped:
Render fidelity: Page body renders 122 elements faithfully. Header/footer templates stored but not emitting DOM - Bricks postTypes option gates render. Not a walker bug, a Bricks config gate.
Next action: Add 1-line REST route (/bsp/v1/bricks/postTypes-add) or set via admin: Bricks > Settings > General > Post Types -> add bricks_template. Then re-fetch confirms header/footer emit.
Logged via nexus_html_logger.py at 2026-04-14T20:44:05.952018 UTC
Purpose: Reproducible steps for taking any Audrey Figma VECTOR/SHAPE node and rendering it inline (not as image asset) inside a Bricks template via child theme. Used for the footer wave (node 652:801). Same pattern works for any shape/wave/divider.
GET https://api.figma.com/v1/images/FILE_KEY?ids=NODE_ID&format=svg&scale=1if ($area_label === footer) {
echo <div class=bsp-footer-wave-wrap style=line-height:0;overflow:hidden;margin-bottom:-1px;>;
echo <svg xmlns=http://www.w3.org/2000/svg viewBox=0 0 414 107 preserveAspectRatio=none style=display:block;width:100%;height:107px;>;
echo <path d=... fill=#1D1760/>;
echo </svg></div>;
}Logged via nexus_html_logger.py at 2026-04-15T00:34:03.535718 UTC
Purpose: reproducible steps for taking any Audrey Figma canvas frame and emitting a clean Bricks Builder 2.3.2 element payload that matches pixel-for-pixel. Uses no walker agents, no post-hoc patches โ pure translate-from-source.
Patching existing walker-generated trees piles on accidental complexity (wrapper divs that dont belong, mis-nested cards, width attributes the Bricks Array bug corrupts). Starting from Figma with clean helpers + consistent measurements gives a tree Bricks can sanitize + render without drift. Patching took 4 sessions of iteration to get close. Rebuild took one deploy.
Logged via nexus_html_logger.py at 2026-04-15T02:06:50.657469 UTC
Purpose: Reproducible recipe for converting any Audrey Figma landing-page design into a Bricks Builder 2.3.2 live page, matching the Figma spec at 95%+ text-content-and-typography fidelity. Uses the bricks-child theme, native-save REST route, and wp_head CSS override for the Bricks 2.3.2 Array bug.
The 10 remaining draft service pages in staging:
Walk canvas children. Record the Desktop frame id (example 602:9 for sewer-camera-inspection at 1440x8162).
For the target frame, list direct children with id, name, absoluteBoundingBox (x, y, width, height).
Use extract_section_spec.py for each section id. Dumps every TEXT node (characters, fontFamily, fontSize, fontWeight, lineHeightPx, color) and every RECTANGLE or VECTOR (name, size, image ref).
H1_TYPO Inter 48 w700 navy / H2_TYPO Inter 36 w400 / H3_TYPO Inter 32 w700 / BODY_22 Inter 22 w400 / BODY_24 Inter 24 w400 / BUTTON_30 Inter 30 w700 white / BUTTON_36 Inter 36 w700 white (final CTA only).
Small factory functions: section(parent, kwargs), block(parent, kwargs), heading(parent, text, typo, tag), text_el(parent, text, typo, tag), image(parent, url, w_px, h_px), button(parent, text, href, bg, typo, w_px, pad, radius). Each returns a Bricks element dict with id + name + parent + children + settings.
For each RECTANGLE with imageRef: curl /v1/images?ids=NODE_ID+format=png+scale=2 and POST to /wp-json/wp/v2/media with Content-Type image/png + filename Content-Disposition. Cache returned id + source_url in an ASSETS dict.
Root section 100% width direction column center align. For each Figma section, wrapper section with its exact Figma width + margin-top matching Figma y-delta from previous section end.
Per-section margin-top defaults for sewer-camera-inspection (reuse as baseline):
Wrap cards in a block with _direction=row _flexWrap=wrap _columnGap=7 _rowGap=7 _width=1135px _alignItems=stretch. Each card block: _width=564px _direction=row _alignItems=center + icon image 120x120 + text block 309 wide Inter 22.
POST /bsp/v2/bricks/native-save JSON body post_id + elements. Confirm response readback_count equals your element count.
POST /bsp/v2/cache/purge then POST Cloudflare /purge_cache purge_everything true. Sleep 4 seconds before re-fetching.
Export Audrey reference: curl /v1/images?ids=FRAME_ID+format=png+scale=1. Capture live: /opt/nexus/venv/bin/python3 /tmp/screenshot_live.py (Playwright + Chromium at viewport 1440 full_page). Spec audit (audit_v2.py): match every Figma TEXT node against live element payload by font-size + font-weight + color + content, tracking used element IDs to avoid duplicate-text collisions. Pixel band diff (diff_images.py): numpy mean per 200px horizontal band. Fix any band with mean diff over 50.
Add to bricks-child functions.php wp_head hook inside if pid equals TARGET_POST_ID branch. Use body.page-id-N::before and ::after with position absolute + top Figma-y + wave PNG background. CRITICAL gotcha: never scope wave pseudo-elements to main#brx-content or add child positioning rules there. It breaks the force-rendered footer. Body-level scoping works reliably.
Child theme bsp_render_bricks_template footer branch injects Figma node 652:801 path as inline SVG before render_content so footer has a wavy top edge matching the navy footer bg. When Audrey provides a combined carved footer asset (baby-blue wave above + navy footer + wave top as one SVG), swap the inline SVG for her export.
Append WIN section to Master History with proof block (element count, CSS rule count, screenshot, Figma text-match percentage). Append recipe section to Battle Plan if page introduces new technique.
Logged via nexus_html_logger.py at 2026-04-15T03:44:19.276810 UTC