# FES Inspector: proper plan (v3, 2026-07-27)

Operator complaint (verbatim):
> "s-10 there's nothing in the panel that can help me with S10 nothing I can
> change the picture anything like that. s-11 I click width and it TT alks a
> bout objects. I'm sorry but you're going to have to do a complete POV ux
> audit of this entire cms there's just so many things that are just not
> understand it okay I clicked on an image and I can't I can't see how to
> change the image rather than just putting a URL what point is that. in so
> many places there's just like a text box where he's supposed to put in a CSS
> or whatever I don't know what you're supposed to do it's not user friendly
> it's not vibe coder friendly I thought I'd ask you to fix all this this is
> meant to be equivalent to elementor or bricks or whatever but it's not it's
> not it's just a dev form based environment. I honestly thought you had
> fixed this but I need you to make a proper plan for this"

## Diagnosis (from audit 01 + 02)

1. **V2 inspector skeleton is fine** — chrome, tabs, panel manager integration
   all work. 3 different screenshots prove it.
2. **V2 control implementations are mostly missing** — 19 of 21 critical
   control types are either not implemented at all, or the .js file doesn't
   exist on the server (returns the WordPress HTML fallback).
3. **`buildFieldsFromSpec` reads the wrong shape** — it expects inspector
   arrays of key strings; the real FES specs have full field objects.
4. **WCP primitive types (typography, border, background, dimensions) are
   not handled at all** — these are the bulk of the field count (about 60
   of 216 fields use primitive types).
5. **No way to "change an image"** — there's no media library picker, no
   drag-and-drop, no file upload, no thumbnail preview. Just a text input
   that takes a URL.
6. **No way to "change a link"** — same problem, no page/post search.
7. **The hand-coded `oscar-module-editor.js` only supports one widget**
   (eael-post-carousel) and is exactly the "boring form" the operator
   described.

## What "world-class" actually requires

For a panel that matches Elementor/Bricks/Brizy quality, each control type
needs:

| Type | Real UX |
|------|---------|
| `text` | Label + input + placeholder + character count + clear button |
| `textarea` | Auto-resize + char count + markdown preview toggle |
| `number` | Label + spinner + min/max + unit picker + linked/unlinked steppers |
| `range` | Label + slider + numeric input side-by-side + step + unit |
| `select` | Searchable dropdown with recent selections + option groups |
| `toggle` | Pill switch with optional label for "on" state |
| `color` | Hex/rgb/hsl input + alpha slider + eyedropper + recent + global |
| `media` | Drag-drop zone + media library modal + URL paste + thumbnail preview + alt + size selector |
| `link` | Type selector (URL/Page/Post/Media/Anchor) + per-type fields + target/nofollow |
| `repeater` | Add/clone/delete items + drag-reorder + per-item expand/collapse |
| `icon` | Icon library browser with search + preview + size + color |
| `typography` | Family picker + 14 sub-controls (size, weight, style, transform, decoration, line-height, letter-spacing, word-spacing, color, align, shadow, stroke, indent, overflow) |
| `border` | 4 edges linked + per-edge style/width/color + radius shorthand |
| `background` | 4 types (color/gradient/image/video) + per-type sub-controls + overlay |
| `dimensions` | 4 sides linked + per-side value + unit picker + auto |
| `alignment` | Visual 9-grid picker + text-align + justify |
| `box_shadow` | Multi-shadow list + per-shadow x/y/blur/spread/color/position |
| `text_shadow` | Same as box_shadow but for text |
| `hover_effects` | Trigger + duration + easing + transform + filter transitions |
| `motion_effects` | Entrance/scroll/hover animations + per-effect config |
| `responsive_visibility` | 3-state toggle per breakpoint + reverse |
| `css_classes` | Multi-tag input with autocomplete from existing classes |
| `custom_css` | Code editor with syntax highlighting + live preview |

That's **23 controls, ~30,000 lines of JS** in total. Not a "fix this bug"
scope. This is **the entire FES project**, properly executed.

## Recommended approach: 4-phase plan

### Phase A — Stabilize what exists (today, 1-2 hours)

Stop the bleeding. The current state has a partially-working v2 inspector
that crashes for ~90% of widgets. Roll back the v2 to opt-in OR keep it
default but **gate it behind a working check**: if any field type that the
spec uses is missing, fall back to the v1 form (which renders the basics
even if it's ugly).

**Deliverable**: Every widget click in the dev panel shows *some* form
(no more "(no fields)" / no more crashes), even if it's not pretty.

### Phase B — Build the missing controls (4-6 days, parallel work)

This is the actual work. I'll spawn a team plan with parallel workers:

- **Worker 1: Media control** (image picker, library, URL, preview, alt)
- **Worker 2: Link control** (type selector, page search, target/nofollow)
- **Worker 3: Typography control** (family + 14 sub-controls)
- **Worker 4: Color picker v2** (alpha, eyedropper, swatches, multiple modes)
- **Worker 5: Repeater + remaining types** (repeater, icon, range, select v2,
  background, border, dimensions, alignment, box_shadow, text_shadow,
  hover_effects, motion_effects, responsive_visibility, css_classes, custom_css,
  toggle)

Each worker delivers a single control file that exposes
`window.FES_CONTROLS_V2.render(type, field, value, onChange, ctx)`. ~1500
lines per control. Total ~30K lines, split across 5 workers.

**Deliverable**: 19 working control files in
`/app-fragments/editor-inspector/controls/<name>/<name>.js` matching
`/workspace/editor-controls/<name>.js` for `text` and `color`.

### Phase C — Fix `buildFieldsFromSpec` to read the real FES spec shape (1 day)

The function needs to:
1. Read `fesSpec.inspector[tabName]` as an array of **field objects**
   (`{id, type, label, options, ...}`), not an array of **key strings**.
2. Handle the WCP primitive types (typography, border, background,
   dimensions, etc) as sub-controls that compose multiple simpler controls.
3. Normalize case variants (TYPOGRAPHY/typography, COLOR/color).
4. Merge `fieldSchema[key]` defaults into the inspector field.

**Deliverable**: Every FES spec renders all its fields, in the right tab,
with the right control type.

### Phase D — Polish + UX audit (2-3 days)

Once controls work:
1. **POV operator flow test** on real WordPress pages with real widgets —
   click every badge, verify the panel actually does what the operator
   expects (image picker → can pick an image from library, link → can
   search for a page, typography → can change font and see the change).
2. **Operator-flow audit script** (already exists at
   `scripts/audit-operator-flow.py` as the operator-flow-criterion
   checker). Add OFC-012: every FES spec must round-trip through the v2
   inspector without "(no fields)" or "object" errors.
3. **Mobile UX** — the panel is currently `380px` wide. On a 390px mobile
   viewport that's almost full-screen. Need to make it responsive
   (full-screen on mobile, centered modal on tablet, floating panel on
   desktop).
4. **Save/load integration** — controls update the in-memory `moduleInstance.config`
   but currently don't persist anywhere. Need to either:
   - Write back to the widget's `data-settings` attribute (like
     `oscar-module-editor` does), OR
   - Open a "Save" button that POSTs to the server, OR
   - Use a draft system (localStorage with "saved / unsaved" indicator).
   This needs operator input on which path to take.

## What I'm NOT going to do (and why)

- **Not going to ship Phase B + C + D in one go** — too much, too risky,
  can't verify the operator gets world-class without their input.
- **Not going to write 30K lines of control code myself** — that's what
  GLM is for (per the Mavis-budget-rule). I'll spawn a team plan with
  parallel workers, each producing 1-2 controls, each verified by an
  independent verifier.
- **Not going to invent new control types or new UX patterns** — the
  patterns are well-established in Elementor/Bricks/Brizy. I'm
  implementing what already works, not inventing.
- **Not going to skip the Phase A stabilization** — the operator
  shouldn't be looking at a broken panel while we build the new one.

## What I need from you, G

1. **Should I roll back the v2 to opt-in for now (Phase A path)** while
   we build the controls? OR keep v2 default but with a smarter
   fallback? I lean toward **smart fallback** — if the v2 can't render
   the spec cleanly, fall back to v1 form. That way the operator
   never sees "(no fields)" or crashes.
2. **For the media picker**: do you want the WordPress media library
   modal (uses WP's built-in media-frame.js) or a custom modal that
   fetches from `/wp-json/wp/v2/media`? The WP one is faster to
   implement but pulls in WP admin code; the custom one is cleaner but
   more work.
3. **For save/persist**: do you want the changes to write back to the
   widget's data-settings attribute (live preview, no server roundtrip),
   or POST to a server endpoint (durable, but needs server work)?
4. **For mobile**: full-screen panel on phone, or smaller floating
   panel that the operator can drag around?
5. **Priority order for the 19 missing controls**: media, link,
   typography, color, repeater — which do you want first?

## Honest assessment

The current FES inspector is **a skeleton with a chrome and no muscle**.
The 23 control names I declared are mostly fiction. The 21 FES specs
are real and well-structured (they describe the fields Elementor
widgets actually have), but nothing renders them. To get to
Elementor-grade, **we need to build 19 real controls** that take
real-world inputs and produce real-world outputs. This is a 4-6 day
project, not a one-shot.

I want to do this properly. The patches I've been shipping were
"make the broken thing less broken" — what you need is a
"make the broken thing actually work" project, with a real plan, real
deliverables, real verification.

**Tell me which path to take** (the 4 questions above) and I'll kick
off Phase A immediately, then queue the team plan for Phase B+C+D.
