A fast, responsive electrician landing site with parallax sections, a 4‑item nav, a contact form, and full Obra CMS integration for live content + design editing.
index.html— main site (production)assets/css/styles.cssassets/js/main.js— event delegation, smooth scrollassets/js/obra-runtime.js— fetches content from Obra API, applies to DOMassets/js/design-component.js— OOP design system (see below)assets/obra/content.json— local fallback content + design schemaassets/Img/— hero, parallax, and logo imagesmain.py— Flask server (contact form, Obra lead forwarding)
Open index.html in your browser, or serve with any static server:
python3 -m http.server 8080- Create a new Static Site on Render.
- Connect your repo.
- Build Command: (leave blank)
- Publish Directory:
/(root) - Headers (optional):
Cache-Controlforassets/*:public, max-age=31536000, immutable
- Hit Create Static Site.
obra-runtime.js fetches GET https://api.obra.cloud/v1/content/watson on every page load.
If the API is unreachable it falls back to assets/obra/content.json.
Fields applied via [data-obra="<dot.path>"] attributes in index.html:
data-obra key |
Element |
|---|---|
banner.text |
.banner |
hero.headline |
h1.headline |
hero.subhead |
p.subhead |
trust.0 – trust.3 |
.trust__item × 4 |
services.0.title – services.3.title |
service card titles |
services.0.desc – services.3.desc |
service card descriptions |
The site runs a lightweight OOP design layer that the Obra client console drives via its Design tab.
obra-runtime.js calls applyDesign(data) after applyContent(data).
"hero": {
"design": {
"backgroundImage": "assets/Img/hero-electric.jpg",
"headlineColor": "#eaf1ff",
"headlineFontSize": "3.5rem",
"subheadColor": "#a4acb9",
"subheadFontSize": "1.15rem"
},
"buttons": [
{ "id": "btn_primary", "label": "Request a Quote", "href": "#contact", "variant": "primary", "size": "lg", "animation": "glow" },
{ "id": "btn_secondary", "label": "See Services", "href": "#services", "variant": "secondary", "size": "lg", "animation": "none" }
]
}- Extend
DesignComponentindesign-component.js - Register it in
DesignComponentRegistry - Add
data-obra-design="<type>"to the section element inindex.html
The OOP design component on this site is the renderer half.
The editor half must be built in the obra-client-console repo.
Use the following prompt when working in that repo:
Context: Watson Electrician's site (
watsonelectriciancomrepo) now has an OOP design component system (assets/js/design-component.js). The hero section reads design settings fromcontent.jsonviaGET /v1/content/watsonand saves them viaPUT /v1/content/{slug}. All design properties live underhero.design.*andhero.buttons[]in the content object (see schema below). The Design tab in the Obra console currently shows no design fields for the hero section.Task: Build a Hero Design tab UI in the Obra client console so editors can visually configure all hero design settings and save them back to the API.
Hero design schema to expose in the UI:
"hero": { "design": { "backgroundImage": "<string — relative path or https:// URL>", "headlineColor": "<CSS color string, e.g. #eaf1ff>", "headlineFontSize": "<CSS font-size string, e.g. 3.5rem — optional>", "subheadColor": "<CSS color string>", "subheadFontSize": "<CSS font-size string — optional>" }, "buttons": [ { "id": "<alphanumeric/hyphens only>", "label": "<button text>", "href": "<# | / | https:// only>", "variant": "primary | secondary", "size": "lg | (omit for default)", "animation": "glow | none" } ] }Acceptance criteria:
- The Hero section's Design tab renders form controls for every field above:
backgroundImage— text/URL inputheadlineColor/subheadColor— color picker (+ hex text input)headlineFontSize/subheadFontSize— text input (optional, leave blank to use CSS default)buttons[]— a list editor: add / remove / reorder buttons, editing id, label, href, variant (select), size (select), animation (select)- Saving calls
PUT /v1/content/{client_slug}with the full updated content object (merge — do not overwrite other sections).- A live preview panel (iframe or side-by-side) re-renders the hero using the same
HeroDesignComponentlogic so editors see changes before saving.- Use
src/lib/obraContent.jsfor all API calls — fix thesaveClientContentmethod if it currently usesPOSTinstead ofPUT(see existing issue).- Form state is initialised from the current content fetched by
GET /v1/content/{client_slug}.- All color inputs must validate as valid CSS colors before saving.
- All
hrefinputs must validate as#…,/…, orhttps?://…before saving.- Do not break existing Content tab fields (
banner.text,hero.headline,hero.subhead,services.*,trust.*).Files likely to change:
src/components/sections/HeroDesign.jsx(create if not present)src/lib/obraContent.js— fixsaveClientContentto usePUTsrc/pages/ClientSection.jsx(or equivalent) — wire in the new Design tab- Any shared
ColorPicker,ButtonListEditorcomponents (create or reuse)No new external dependencies unless a color-picker component is already in the project. Do not change the Watson site (
watsonelectriciancom) repo.
- Parallax uses
background-attachment: fixed; on mobile it falls back to non-fixed for performance. - Colors are adjustable in
:rootCSS variables. - The
lab/directory contains experimental sandbox pages (not deployed).