Final phase of the hero canvas editor (see HERO_EDITOR.md) — v1 complete.
- element tray adds moon, badge, and image; property panels:
- moon: size / glow / color
- badge: text / background / text color / corner radius
- image: upload (/admin/uploads, >1MB warning) / width% / alt
- corner resize handle on selected elements (image→width%, moon→size,
text_block→box width)
- 8px snap-grid toggle with a faint canvas grid overlay; drag snaps when on
- HeroElement: image element shows an "Upload an image" placeholder until a
source is set (a srcless image never ships live)
Verified in-browser: all five element types add + edit; moon resized 64->104px
via the handle; snap grid overlays; a published moon + badge render on the live
portal; no console errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Third phase of the hero canvas editor (see HERO_EDITOR.md).
- HeroElement: editor mode — inner content made non-interactive so the wrapper
handles select/drag; selection outline; box width now canvas-relative
(calc(100% - 36px)) so text blocks fit the smaller editor canvas
- HeroEditor: element tray (+ Text / + Buttons), click-to-select, native
Pointer Events drag (position as % of the canvas, clamped), Delete key + panel
delete, z-order (send back / bring forward), and per-type property panels:
- text_block: per-line text / tag / font size (px) / color / bold, add+remove
lines, alignment
- buttons: per-item label / path / variant, add+remove, alignment
empty-canvas click deselects (back to the background panel)
- theme.css: .hero-el-editable outline/hover/selected + grid helper
Verified in-browser: selecting shows the line editor, editing updates the canvas
live, drag repositions, add/delete and z-order work, deselect returns to the
background panel; no console errors. Moon/badge/image + resize + snap are Phase 4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Second phase of the hero canvas editor (see HERO_EDITOR.md).
- new lib/heroLayout.js: shared defaultLayout/buildOverlay/heroBackground/
parseLayout used by both the portal and the editor (Portal refactored onto it)
- new admin view HeroEditor.jsx at /admin/hero (+ sidebar nav + route):
- live canvas preview (16:9) rendering the draft via HeroElement
- background panel: image upload (/admin/uploads, >1MB warning), 3x3 position
grid, overlay opacity slider — all update the canvas in real time
- debounced (800ms) auto-save to hero_layout_draft
- Publish (writes hero_layout + draft), Preview (opens /?preview=1), Revert
- Portal: ?preview=1 renders the draft via the admin settings endpoint, with a
"showing unpublished draft" banner; normal load renders the published layout
No schema/dep changes. Verified end to end: overlay/position update the canvas,
auto-save writes the draft, publish updates the live portal, preview shows the
draft while the public page shows live. Element drag/properties land in Phase 3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Build contract for the WYSIWYG portal-hero editor on hero-feature, derived
from the design doc and corrected against the codebase:
- public settings is a whitelist (getPublic/PUBLIC_KEYS), so hero_layout must
be added there — the doc's "no backend changes" was wrong
- moon is the reusable MoonDot component; route vs nav live in App.jsx vs
AdminLayout.jsx; admin content is 1000px (canvas scales to fit)
Locked decisions: full v1, buttons as a first-class element type, pre-populate
the current hero on first run, native Pointer Events for drag. Phased plan
with per-phase exit checks. No schema change (JSON in settings).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>