# Profen Engineering — React SPA
A React single-page application that recreates [profeneng.com](https://profeneng.com) (WordPress + Elementor + Rakar theme) as a fast, portable frontend.
## Architecture
```
src/
├── main.jsx Entry — imports CSS (variables → kit → theme → layout → pages → services → dynamic), mounts React
├── App.jsx Router (BrowserRouter, Suspense, ErrorBoundary, lazy-loaded pages, 404 route)
├── config.js Central config: WhatsApp phone, brand colors, PAGE_IDS, SPA_ROUTES, POST_ID_TO_SLUG, SERVICE_SIDEBAR_ITEMS, MENU_ITEM_IDS
├── components/
│ ├── Layout.jsx Shared layout (Header + Outlet + Footer + WhatsAppButton + preloader + page‑id body class)
│ ├── SafeHtml.jsx Parses HTML strings into React elements via html-react-parser (replaces dangerouslySetInnerHTML)
│ ├── ErrorBoundary.jsx Catches render crashes, shows Try Again button
│ ├── Loading.jsx Spinner for Suspense fallback
│ ├── WhatsAppButton.jsx Floating WhatsApp widget
│ └── sections/
│ ├── Header.jsx Proper React component with nav, active state from useLocation()
│ ├── Footer.jsx Proper React component with contact data, social links, service links
│ ├── Breadcrumb.jsx Reusable breadcrumb trail
│ ├── SectionTitle.jsx Section heading with subtitle & icon
│ ├── Button.jsx Reusable styled button
│ ├── PhoneWidget.jsx Phone call widget
│ ├── FeatureCards.jsx Feature card grid
│ ├── ContactForm.jsx "Get a Quote" form
│ ├── ContactInfo.jsx Address/phone/email display
│ ├── GoogleMap.jsx Embedded Google Maps iframe
│ ├── Divider.jsx Section divider
│ ├── ProjectFilterGrid.jsx Filterable project grid
│ ├── ServiceContentBlocks.jsx Renders structured service content (paragraphs, headings, lists)
│ ├── ServiceGridSection.jsx Service listing grid
│ ├── ServiceBreadcrumb.jsx Service detail breadcrumb
│ ├── ServiceImage.jsx Service detail featured image
│ ├── ServiceBody.jsx Service detail body (content blocks)
│ └── ServiceSidebar.jsx Service detail sidebar nav
├── pages/
│ ├── Home.jsx Page: / — uses SafeHtml (parses home-content.html)
│ ├── About.jsx Page: /about — uses SafeHtml (parses about-content.html)
│ ├── Services.jsx Page: /service — uses SafeHtml (parses service-content.html)
│ ├── ServiceDetail.jsx Page: /service/:slug — fully componentized, reads services.json
│ ├── Project.jsx Page: /project — fully componentized, uses ProjectFilterGrid
│ └── Contact.jsx Page: /contact — fully componentized, uses section components
├── hooks/
│ ├── useLayoutInit.js Re-initializes Elementor theme JS on route change (requestAnimationFrame polling)
│ ├── useNavFix.js Intercepts links inside a ref for proper SPA routing
│ └── useThemeAssets.js Injects and tags (OG, canonical, favicon) on mount
├── data/ Content sources
│ ├── home-content.html Home page HTML content (parsed by SafeHtml)
│ ├── about-content.html About page HTML content (parsed by SafeHtml)
│ ├── service-content.html Services listing HTML content (parsed by SafeHtml)
│ └── services.json Structured data for 9 service detail pages (contentBlocks, images, metadata)
└── css/ Build-time CSS imports (all bundled into one index-*.css)
├── variables.css :root CSS custom properties for brand colors (imported first)
├── kit.css Elementor kit CSS (global styles)
├── theme.css Rakar theme overrides
├── layout.css Header (elementor-945) + Footer (elementor-1098 / elementor-128) CSS
├── pages.css Combined CSS for all 5 main pages
├── services.css Combined CSS for all 9 service detail pages
├── dynamic.css Dynamic overrides using var(--brand-*) with fallbacks
└── pages/ Individual page CSS files (development reference — edit these, then regenerate combined)
├── page-23.css Home page
├── page-31.css About page
├── page-32.css Services listing
├── page-36.css Project page
├── page-48.css Contact page
└── service-*.css Individual service detail pages (9 files)
```
## Strategy: Hybrid React + WordPress Content
The app uses a **hybrid approach**:
1. **Componentized pages** (Contact, Project, ServiceDetail) use proper React section components with structured data — no HTML strings.
2. **Transitional pages** (Home, About, Services) render raw Elementor HTML from `src/data/*.html` files, parsed at runtime by `html-react-parser` via `SafeHtml.jsx` — **no `dangerouslySetInnerHTML`** anywhere in the app.
3. **Styling** comes from two places:
- Build-time CSS imports (`src/css/*.css`) — Elementor's page-specific CSS bundled by Vite
- Runtime assets from `public/wp-content/` — theme stylesheets, fonts, images
4. **Behavior** comes from the original Rakar theme JS loaded via `