**Repo**: `avidtech6/freshvibe-cms` v1.2.0, vendored at `/workspace/fv-module-gallery/fv-cms-vendored/`
**Released**: 2026-08-05 by helper-mavis session 412100071272671
**Manifest**: `fv-cms-manifest.001` (`FV-CMS-MANIFEST.json`)
**Source of truth**: `git log` not available (vendored snapshot); the manifest is the build-of-record.
---
**FES = FreshVibe Element Schema.** The 16-element vocabulary the runtime dispatches. Per the FES doctrine (a761 §2.1), each module pack is `id + schema + defaultConfig + ui + editor + variants`, NOT a renderer — the chrome reads it at runtime, wires the inspector, and lets the live DOM update.
The **dual-layer** rule (id 8's doctrine, post-d529c91):
The FvCMS runtime imports from the gallery and re-dispatches under the M-prefix.
---
From `fv-cms-vendored/runtime/renderer.js` (560 lines) and `fv-cms-vendored/detectors/elementor.js` (530 lines), cross-referenced:
| Runtime ID (M-prefix) | Schema ID | Elementor widget types handled | Detector config shape | Renderer registered |
|---|---|---|---|---|
| M-accordion | accordion | eael-adv-accordion, eael-toggle | items[], multiOpen, style, iconPosition | ✓ |
| M-breadcrumb | breadcrumb | eael-breadcrumbs | items[], separator, homeLabel | ✓ |
| M-button | button | button, eael-creative-button | text, href, variant, radius, size, openInNewTab, icon | ✓ |
| M-carousel | carousel | eael-post-carousel, eael-team-member-carousel, eael-stacked-cards | items[], visibleCount, autoRotate, rotateInterval, showDots, showArrows, cardStyle, imageAspect | ✓ |
| M-contact-form | contact-form | form, eael-weform, eael-fluentform | fields[], submitLabel, submitEndpoint, successMessage, layout | ✓ |
| M-cta | cta | button, eael-creative-button | text, href, variant, color, radius, size, openInNewTab, icon | ✓ |
| M-cta-box | cta-box | eael-cta-box | title, body, buttonText, buttonHref, background, layout | ✓ |
| M-heading | heading | heading, animated-headline | text, level, align, color, size | ✓ |
| M-icon-list | icon-list | icon-list | items[], layout, iconColor, spacing | ✓ |
| M-image | image | image, eael-image | src, alt, width, align, aspectRatio, caption, link | ✓ |
| M-info-box | info-box | eael-info-box | icon, title, body, link, linkLabel, variant | ✓ |
| M-menu | menu | eael-simple-menu | items[], layout, align, showIcons, separator | ✓ |
| M-paragraph | paragraph | text-editor | text, size, align, color, maxWidth | ✓ |
| M-social-icons | social-icons | social-icons | platforms[], shape, size, color, align, layout | ✓ |
| M-testimonial | testimonial | premium-addon-testimonials, eael-testimonial | quote, authorName, authorRole, authorImage, rating, style | ✓ |
| M-video | video | video, eael-video | source, url, poster, autoplay, loop, muted, aspectRatio, caption | ✓ |
**Total: 16 modules dispatched.** Both renderer.js and detector.js share the same vocabulary. The detector's `mapWidgetToModule()` is the single source of truth for "what FES understands."
---
The detector doesn't directly read CSS breakpoints. FES uses the **5 standard breakpoints** (per a761 §2.3 — `responsive.json` schema): mobile (≤480), mobile-wide (≤767), tablet (≤1024), laptop (≤1366), desktop (default).
The inspector control `app-fragments/editor-inspector/controls/responsive/` is the manual override surface.
FES reads:
---
| Panel ID | Kind | Path | Source |
|---|---|---|---|
| cms-panel | panel | app-fragments/fvcms-cms-panel/ | freshvibe-cms v1.1.0 (post-oscar rename) |
| dev-btn | fragment | app-fragments/fvcms-dev-btn/ | freshvibe-cms v1.1.0 |
| dev-panel | panel | app-fragments/fvcms-dev-panel/ | freshvibe-cms v1.1.0 |
| floating-buttons | fragment | app-fragments/fvcms-floating-buttons/ | freshvibe-cms v1.1.0 |
| module-editor | fragment | app-fragments/fvcms-module-editor/ | freshvibe-cms v1.1.0 |
| panel-manager | panel | app-fragments/fvcms-panel-manager/ | freshvibe-cms v1.1.0 |
| region-editor | fragment | app-fragments/fvcms-region-editor/ | freshvibe-cms v1.1.0 |
| trace | fragment | app-fragments/fvcms-trace/ | freshvibe-cms v1.1.0 |
| watermark-hider | fragment | app-fragments/fvcms-watermark-hider/ | freshvibe-cms v1.1.0 |
The 16 M-prefixed modules listed in §2, each registered with `kind: 'module', tier: 'tier-2'`, `canonical_home: avidtech6/fv-module-gallery/cms-widgets/`.
**Gallery-to-FvCMS re-export pattern**: gallery owns the source, FvCMS re-exports the M-prefixed runtime ids. This is the dual-layer doctrine in action.
From `app-fragments/editor-inspector/controls/`:
| Control | Purpose |
|---|---|
| ai-assist | AI-powered edit suggestions |
| backdrop-filter | CSS backdrop-filter |
| background-color | Solid background color |
| background-gradient | Linear/radial gradient |
| background-image | Image background |
| background-unsplash | Unsplash picker |
| bg-tabs | Tabbed control groups (backgrounds) |
| color | Color picker |
| dimension | Width/height/padding/margin |
| dropdown | Dropdown selector |
| filters | CSS filter (blur, brightness, etc.) |
| motion-entrance | Entrance animation picker |
| motion-grid | Motion grid (preset combinations) |
| motion-trigger | Scroll/hover/click triggers |
| number | Numeric input |
| pills | Pill-style multi-select |
| radius | Border-radius |
| responsive | Breakpoint override |
| shadow-multi | Multi-layer box-shadow |
| slider | Range slider |
| switch | Boolean toggle |
| tags | Tag input |
| text | Text input |
| textarea | Multi-line text |
**These 24 controls are the FES inspector's field-type vocabulary.** Any new FES module's `fieldSchema` must use these control ids.
`bootstrap.js` (45 lines) → `runtime/index.js` → `runtime/load-annotation.js` → `runtime/renderer.js` → `runtime/region-renderer.js` → `runtime/region-actions.js` → `runtime/editor-shell.js` → `runtime/inline-editor.js` → `runtime/form-editor.js` → `runtime/visualizer.js` → `runtime/skin.js` (with `SAMPLE_SKINS`).
The full flow:
1. Page loads → bootstrap.js runs
2. `annotation.json` fetched from URL (or passed inline)
3. `loadAnnotation()` parses it into the store
4. `findPage(pathname)` matches the current URL
5. `region-renderer.js` walks the regions, `renderer.js` walks the modules
6. `registerRenderer('M-...', fn)` lookup dispatches each module
7. For each module: get config from store, apply skin, mount to `[data-fvcms-module-id]`
---
| | App-Builder Landscape (a761) | FES dispatch (audit) | Gallery has |
|---|---|---|---|
| Total roles | 93 | 16 (17%) | 16 (17%) |
| Canonical 15 | 15 | **7 (47%)** | **7 (47%)** |
These are the "must-have" set per a761 §3.13 — explicitly called out as the minimum for world-class. FES dispatches NONE of them:
| A761 canonical name | Why it's canonical | What FES would need to do |
|---|---|---|
| **form** | The superset form: 50+ field types, 30+ actions, 3-level conditional logic, multi-step | Already have `M-contact-form` — would be a superset/rename |
| **gallery** | The image gallery primitive (not just single image) | New module: 6 variants, lightbox, masonry, slideshow, etc. |
| **icon** | Standalone icon primitive (Fa + Lucide + custom) | New module: icon picker, sizing, color, link |
| **map** | Map embed (Google/Mapbox/OSM) | New module: lat/lng/address, marker, style |
| **modal** | Modal dialog primitive | New module: trigger, content, dismiss, focus trap |
| **pricing-table** | SaaS pricing table | New module: tiers, features, highlight, CTA |
| **query-loop** | Dynamic data loop (post-grid, post-carousel, archive, glossary) | New module: query args, template, pagination |
| **tabs** | Tabbed content | New module: tab triggers, panels, keyboard nav |
Full A761 inventory vs FES coverage:
| A761 category | Total roles | In FES today | Missing |
|---|---|---|---|
| Layout primitives | 10 | 0 (none) | section, container, column, block, div, grid, stack, row, header, footer |
| Content display | 10 | 4 (heading, paragraph, image, button) | text (renamed→paragraph), image-box (renamed→image), icon, icon-box, buttons-group, list-group, divider, spacer |
| Structural & nav | 12 | 2 (accordion, breadcrumb) | tabs, toggle, modal, popup, off-canvas, sticky, mega-menu, navigation (→menu), pagination, search |
| Dynamic content | 12 | 0 | query-loop, single-field, single-product, archive, user-author, relation, glossary, post-grid, post-carousel, post-list, product-grid, product-carousel |
| Forms | 1 | 0 (have contact-form) | form (superset) |
| Interactive | 5 | 0 | image-compare, image-hotspot, image-mask, lottie, marquee |
| Data viz | 8 | 0 | counter, progress-bar, progress-arc, chart, timeline, process, data-table, pricing-table |
| Media & embed | 6 | 2 (video, social-icons) | audio, gallery, social-share, map |
| Marketing | 12 | 3 (cta, cta-box, testimonial) | banner, testimonial-grid, testimonial-carousel, team-member, team-grid, logo-grid, logo-carousel, news-ticker, weather |
| Engagement | 8 | 0 | reading-progress, scroll-to-top, cookie-consent, age-verification, coming-soon, maintenance, paywall, membership-gate |
| WooCommerce | 5 | 0 | product-single, cart, checkout, my-account, mini-cart |
| Theme templates | 4 | 0 | theme-header, theme-footer, theme-single, theme-archive |
**Total gaps: 8 canonical + 67 non-canonical = 75 missing modules.** Of those, 8 are canonical (must-have) and 67 are non-canonical (nice-to-have per builder tier).
---
FES detector handles 23 Elementor widget types. **The standard Elementor core + EAEL install has ~120 widgets.** Coverage = 19%.
Unhandled Elementor widget types (would fall to `default: null`, no FES module dispatched):
**The detector is the chokepoint.** Every widget the detector doesn't recognize = invisible to FES = invisible to the inspector. The Oscar dist has 11,535 `data-fvcms-region` markers but only a fraction of those will have a dispatched FES module.
---
1. **The dual-layer doctrine holds.** Schema IDs lowercase, runtime IDs M-prefixed. FES consumes the M-prefixed ids at runtime. The detector is M-prefixed, the renderer is M-prefixed, the chrome-registry is M-prefixed. Clean separation.
2. **The dispatch is locked.** 16 modules, all 16 registered in `renderer.js`, all 16 in `chrome-registry/index.json`, all 16 in `detectors/elementor.js`. No drift between the three. **This is gallery + FES in lockstep.**
3. **The inspector controls are reusable.** 24 control types cover 100% of the 16 current modules' `fieldSchema` shapes. Any new module reuses these, no new control type needed unless we add something exotic (e.g. color picker with alpha + swatch library).
4. **The region/module/group data model is solid.** Pages contain regions (top-level e-con), each region has groups (widgets), each group has module instances. The annotation.json schema (`data-model.md`) is the contract; the runtime consumes it; the editor produces it.
5. **Skin system is decoupled.** `SAMPLE_SKINS` in `skins/index.js` + `applySkin()` + `registerSkin()` API. Adding a new skin = no module change.
---
1. **Coverage is 17% of the App-Builder universe.** That's not a "world-class" module set — it's a starting set. The 8 missing canonical modules are the priority.
2. **The detector is the chokepoint.** ~19% of common Elementor widgets are dispatched. The rest are silently null. This makes the inspector useless on real Oscar / Hopfan sites where most widgets are eael-*.
3. **`menu` is single-source = `eael-simple-menu`.** No fallback to WordPress nav, no walker.js path. Hopfan's nav will likely be a default WP menu, not eael-simple-menu, and FES won't recognize it.
4. **Form superset is split between 3 elementor widgets** (`form`, `eael-weform`, `eael-fluentform`) but dispatched to ONE FES module (`M-contact-form`) with a generic config shape. The 50+ field types / 30+ actions / multi-step from A761 §3.5 are not modeled.
5. **No layouts at all.** A761 has 10 layout primitives (section, container, column, grid, stack, row, header, footer, block, div). FES has zero. The region detector reads `.e-con` but doesn't model it as a dispatchable module — the inspector can't add a new region programmatically.
6. **No dynamic data.** A761 has 12 dynamic roles (query-loop, single-product, archive, post-grid, etc.). FES has zero. The carousel module is the closest, but it doesn't query, it just renders.
7. **No interactions / animations / conditions.** A761's 6 behavior matrices (interaction, animation, dynamic binding, conditional logic, responsive, edge cases) are entirely absent from the FES module schema. Modules are static renderers.
8. **Inspector control set is finite.** 24 controls, no custom control type registry. New module = new field type = new control, OR the field type is forced into an existing control (lossy).
---
| Audit dimension | Result |
|---|---|
| FES dispatch set | 16 modules (M-accordion, M-breadcrumb, M-button, M-carousel, M-contact-form, M-cta, M-cta-box, M-heading, M-icon-list, M-image, M-info-box, M-menu, M-paragraph, M-social-icons, M-testimonial, M-video) |
| Elementor widgets handled | 23 types → 16 FES modules (3 form variants collapse to M-contact-form, 3 carousel variants collapse to M-carousel) |
| Elementor widgets NOT handled | ~97 (standard core, all Pro dynamic, all EAEL extensions except the 23 above) |
| A761 §3.13 canonical 15 coverage | 7/15 dispatched (heading, paragraph, image, button, accordion, testimonial, video); 8 missing (form, gallery, icon, map, modal, pricing-table, query-loop, tabs) |
| A761 total roles coverage | 16/93 (17%) |
| Inspector controls | 24 (text, textarea, number, color, dimension, dropdown, slider, switch, tags, pills, responsive, radius, shadow-multi, backdrop-filter, background-{color,gradient,image,unsplash,tags}, motion-{entrance,grid,trigger}, filters, ai-assist) |
| Data attributes consumed | data-id, data-widget_type, data-settings, data-fvcms-{module-id,type,update}, data-region-content, data-{block,field,panel}-name, data-{id,settings,widget} |
| CSS contract | --fvcms-* custom properties, scoped per module |
| Breakpoints | 5 standard (mobile/mobile-wide/tablet/laptop/desktop) + container queries |
| Layout signals | region order, widget order, nested vs flat (top-level e-con only) |
| Strongest area | dual-layer doctrine, dispatcher integrity, skin system, data model |
| Weakest area | Elementor widget coverage (~19%), canonical completeness (47%), zero dynamic data, zero layouts, zero interactions/animations |
---
FES today is **stable and internally consistent** but **incomplete** by the App-Builder Landscape standard. The gallery has the same shape. To go from "16 modules" to "world-class," the priority order is:
**Tier 1 (canonical 8 missing — must add)**:
1. `icon` (M-icon) — simplest, foundational
2. `tabs` (M-tabs) — high-frequency content pattern
3. `modal` (M-modal) — high-frequency UI primitive
4. `form` (M-form) — superset M-contact-form, 50+ field types
5. `gallery` (M-gallery) — superset M-image, lightbox/masonry
6. `map` (M-map) — embed primitive, low complexity
7. `query-loop` (M-query-loop) — the dynamic data foundation
8. `pricing-table` (M-pricing-table) — marketing canonical
**Tier 2 (frequently missing on real sites — add for Oscar/Hopfan coverage)**:
9. `divider` (M-divider) — trivial, high-frequency
10. `spacer` (M-spacer) — trivial, high-frequency
11. `counter` (M-counter) — data viz entry
12. `progress-bar` (M-progress-bar) — data viz entry
13. `timeline` (M-timeline) — content pattern
14. `data-table` (M-data-table) — data viz
15. `lottie` (M-lottie) — animation primitive
16. `marquee` (M-marquee) — engagement
**Tier 3 (must add to detector for Elementor coverage)**:
17. eael-info-box (already in FES)
18. eael-team-member (gallery module, NOT in FES dispatch yet)
19. eael-pricing-table (after Tier 1 #8 lands)
20. eael-timeline (after Tier 2 #13 lands)
21. eael-flip-box
22. eael-modal-popup
23. eael-countdown
24. eael-business-hours
25. eael-faq
26. eael-filterable-gallery
27. eael-image-comparison
28. eael-image-hotspot
29. eael-logo-carousel
30. eael-mailchimp
31. eael-price-menu
33. eael-progress-bar (after Tier 2 #12)
34. eael-protected-content
35. eael-skill-bar
36. eael-table (after Tier 2 #14)
37. standard Elementor core (icon, icon-box, divider, spacer, counter, progress, star-rating, flip-box, call-to-action, countdown, toggle, tabs, search-form, page-title, all loop-*)
**Tier 4 (must add to schema for behavior support)**:
38. responsive.json (per-module breakpoint overrides)
39. conditions.json (visibility, conditional logic)
40. dynamic.json (data binding)
41. interactions.json (hover, click, scroll triggers)
42. edge.json (edge case behaviors)
**Tier 5 (must add for layouts)**:
43. section (M-section) — top-level region creator
44. container (M-container) — block-level region
45. column (M-column) — vertical layout
46. grid (M-grid) — CSS grid wrapper
47. row (M-row) — horizontal flex
48. stack (M-stack) — vertical flex
49. block (M-block) — generic block
50. header (M-header) — theme header
51. footer (M-footer) — theme footer
**Total: 51 new modules + detector expansion + schema expansion + 24-control surface stays.** That's the world-class target.
The plan is in the companion document: `/workspace/WORLD-CLASS-MODULE-PLAN-2026-08-26.md`.
---
— Mavis (helper-mavis, id 10, session 412100071272671)
2026-08-26 21:55 UTC