# FES Inspector Controls — World-Class Spec (v2 → v3)

**Date**: 2026-07-22
**Operator feedback**: "users are not technical they don't know what to put, they need to be guided there needs to be well thought out controls for everything"
**Reference**: Elementor v3 + Bricks 1.11 — what a non-technical user expects when they click a control.

## The 6 problems with v2 controls (right now)

1. **Empty text inputs** — clicking "Margin" or "Background" shows a blank textbox. Non-technical users have no idea what to type. Elementor shows a dimension widget with linked sides, units dropdown, +/- steppers.
2. **No device toggle** — all controls are desktop-only. Bricks and Elementor show a desktop/tablet/mobile icon next to every responsive control so users can set "20px on mobile, 40px on desktop".
3. **Color picker is a tiny swatch** — no eyedropper, no palette, no transparency. Elementor shows a full color picker with global colors, recent, palette.
4. **Background type is a hidden value** — user can't see "Classic / Gradient / Video / Slideshow" as a tab. Bricks uses a 4-tile picker for background type.
5. **Typography is 6 separate fields** — font, size, weight, line-height, letter-spacing, color, transform. Each is a text input. Elementor groups all of this into one Typography block with logical presets.
6. **Visibility is 3 checkboxes** — easy to miss. Elementor uses 3 "device icon" pills with eye on/off icons that say "Hide on Desktop / Tablet / Mobile".

## The 24 world-class controls (target)

**Naming convention**: each control name = the USER-FACING thing, not the CSS concept.
E.g. `spacing` not `padding-margin`, `background_type` not `bg-classic-or-gradient`.

### Layout (5 controls)
- `content-width` — Boxed / Full Width / Custom (segmented control, with width slider if Custom)
- `columns-gap` — None / Small / Default / Wide / Custom (segmented + slider for Custom px)
- `min-height` — slider (0–1000px) + unit (px/vh) toggle
- `vertical-align` — Top / Center / Bottom / Stretch (icon row, 4 visual icons)
- `html-tag` — searchable dropdown (div, section, article, header, footer, aside, main, nav)

### Spacing (3 controls — Elementor pattern)
- `padding` — linked-chains-icon top/right/bottom/left, each with number input + unit (px/em/%/rem/vh) dropdown. Click chain to link/unlink. Link remembers state (Bricks feature).
- `margin` — same as padding but with "negative" auto-set indicator.
- `spacing` — combined margin+padding toggle (Elementor "spacing" preset, default = 0).

### Background (4 controls — Bricks 4-tile picker pattern)
- `background-type` — 4 visual tiles: Classic / Gradient / Video / Image. Each tile shows a preview.
- `background-color` — full color picker: eyedropper, palette, transparency, recent, global colors.
- `background-gradient` — 2-stop / 3-stop / multi-stop editor. Linear / Radial / Conic. Angle slider for linear.
- `background-image` — image picker with Media Library modal: URL paste / WordPress media library / Unsplash / "From URL". Plus size dropdown (Cover/Contain/Auto), position (9-tile visual picker), repeat, attachment (scroll/fixed), blend mode.

### Border (3 controls)
- `border-style` — None / Solid / Dashed / Dotted / Double / Groove (visual swatch picker)
- `border-width` — linked top/right/bottom/left chain
- `border-radius` — linked 4 corners chain (TL/TR/BR/BL), with the Bricks feature of drag-to-set-all

### Shadow (1 control — multi-shadow like Box-Shadows.io)
- `box-shadow` — vertical list. Each row: color picker + x/y/blur/spread inputs + inset toggle. + button to add. X to remove. Live preview box.

### Typography (1 grouped control — Elementor pattern)
- `typography` — 4 font-family cards (Body / Heading / Link / Accent). Click one to expand:
  - Font Family (searchable dropdown of web-safe + Google fonts)
  - Size (slider + number + unit px/em/rem)
  - Weight (Thin/Light/Regular/Medium/SemiBold/Bold/Black as visual swatches)
  - Style (Normal / Italic / Oblique — 2 icons)
  - Transform (None / UPPERCASE / lowercase / Capitalize)
  - Decoration (None / Underline / Overline / Line-Through)
  - Line Height (slider 0.5–3.0)
  - Letter Spacing (slider -10 to +20)
  - Word Spacing (slider)
  - Color (full color picker)
  - Align (Left / Center / Right / Justify)

### Sizing (2 controls)
- `width` — slider 0–2000px + unit (px/%/vw/auto)
- `height` — slider 0–2000px + unit (px/vh/auto)

### Position (2 controls)
- `position` — Static / Relative / Absolute / Fixed / Sticky (icon row)
- `z-index` — number with up/down stepper

### Visibility (1 control — Bricks "eye" pills)
- `responsive-visibility` — 3 device pills (desktop/tablet/mobile icons) with eye on/off. Defaults all-on. Single tap toggles.

### Classes & IDs (1 control)
- `css-classes` — token input with autocomplete. Built-in tokens (.button, .card, .shadow, .rounded, .hide-mobile, etc.) + custom class input. Show as chips with X to remove.

### Image (1 control)
- `image` — image picker with Media Library modal. Shows current image preview thumbnail. Includes "Choose Image" / "Replace" / "Remove" actions.

### Link (1 control)
- `link` — URL input + "Open in new tab" toggle + "No follow" toggle + "Add rel=nofollow" toggle. Shows link icon when active.

### Misc (4 controls)
- `alignment` — Left / Center / Right / Justify (4 visual icons)
- `slider` — number with slider, min/max/step from field config
- `switch` — iOS-style toggle (large, accessible, with on/off labels)
- `tags` — chip input for arrays (e.g. CSS class array, hashtag array)

## The control "container" — what every control has

Every control is wrapped in a `.fes-control` div with this structure:
```
.fes-control
├── .fes-control-label-row
│   ├── .fes-control-label    (e.g. "Padding")
│   ├── .fes-control-responsive-icon  (desktop/tablet/mobile, click to switch)
│   └── .fes-control-info      (small ⓘ icon with tooltip)
├── .fes-control-body
│   └── (control-specific UI)
└── .fes-control-hint     (subtle gray hint text below)
```

If the field is "responsive" (margin, padding, font-size, etc.), the responsive icon shows. Click it to cycle through devices. The label changes to "Padding (Tablet)" while editing tablet.

## How the dispatcher knows which control to use

The FES spec's `fieldSchema` is the source of truth. Each field has:
```json
{
  "margin": {
    "type": "spacing",
    "label": "Margin",
    "responsive": true,
    "scope": "advanced",
    "default": {"top": 0, "right": 0, "bottom": 0, "left": 0, "unit": "px", "linked": true}
  }
}
```

The dispatcher's `_renderField()` looks at `field.type` and routes to the right control:
- `type: "spacing"` → spacing control
- `type: "color"` → color control
- `type: "background"` → background-type picker that opens the background sub-control tree
- `type: "typography"` → typography control
- `type: "select"` → dropdown
- `type: "text"` → text control (last resort, with placeholder + validation)

## The 4 changes to make to v2 controls

1. **Replace the simple `<input type="text">` with a real control** for spacing, color, background, image, etc. Most of the 14 controls in `phase-a/controls/` are text inputs that need to become proper widgets.

2. **Add the device toggle to the control container** — desktop/tablet/mobile icons next to every responsive control. Dispatcher passes the active device, control stores per-device values.

3. **Group related fields** — Typography pulls 11 sub-fields into one expandable block. Background pulls type/color/image/overlay. Border pulls style/width/radius/color. Reduces visual noise.

4. **Add presets** — "None / Small / Default / Large" for gap, padding, border-radius. Users pick the preset, get the right values. Override any side.

## What to build this session (priority order)

1. ✅ `background-type` (4-tile picker) — replaces empty text input
2. ✅ `background-color` (full color picker) — replaces tiny swatch
3. ✅ `background-image` (media library picker) — replaces URL text input
4. ✅ `background-gradient` (gradient editor) — replaces nothing (was missing)
5. ✅ `spacing` (margin/padding) — replaces 4 separate empty text inputs
6. ✅ `border-radius` (4-corner chain) — replaces empty text input
7. ✅ `box-shadow` (multi-shadow list) — replaces empty text input
8. ✅ `typography` (grouped font + size + weight + ...) — replaces 6 separate fields
9. ✅ `responsive-visibility` (3 device pills) — replaces 3 checkboxes
10. ✅ `css-classes` (token picker w/ built-ins) — replaces empty text input
11. ✅ `slider` with unit (px/%/em/rem) — replaces number-only
12. ✅ `alignment` (4 visual icons) — replaces dropdown
13. ✅ `width` / `height` (slider + unit) — replaces number-only
14. ✅ `image` (media library picker) — replaces URL text input
15. ✅ `link` (URL + toggles) — replaces URL text input
16. ✅ `content-width` (segmented control)
17. ✅ `columns-gap` (segmented + slider)
18. ✅ `min-height` (slider + unit toggle)
19. ✅ `position` (icon row)
20. ✅ `z-index` (number stepper)
21. ✅ `html-tag` (searchable dropdown)

## The build process (no shortcuts this time)

For each control above, write a clear spec, run GLM, then MANUALLY review the output before applying. Don't ship empty input boxes. Don't ship without a label, a hint, and a default value that makes sense.

Every control must have:
- A visible LABEL (e.g. "Padding", not "padding_top")
- A HINT (1-line description, e.g. "Space inside the section border")
- A DEFAULT value (don't start empty)
- A meaningful PLACEHOLDER if a value is needed (e.g. "Type a number or use the slider")
- A VALIDATION (red border on invalid)
- A RESPONSIVE indicator (if applicable)
- AN ICON in the field type icons (Bricks-style: a small icon next to the label that shows what kind of field it is)

## What NOT to do (lessons from v2)

- ❌ No empty `<input type="text">` for any CSS-property field (margin, padding, background, color, etc.)
- ❌ No 6 separate text inputs for typography (font + size + weight + line-height + letter-spacing + color)
- ❌ No "type a JSON value here" for box-shadow or background
- ❌ No "default: null" anywhere — every field must have a sensible default that does nothing or shows a clear empty state
- ❌ No checkboxes for responsive visibility — use eye pills
- ❌ No dropdown-only color picker — need swatch + hex input + eyedropper
- ❌ No 4-tile background picker that doesn't show what each tile is

## Timeline

This is a real redo of the controls. Estimate: 2-3 sessions of focused work.
- Session 1 (now): Replace the 6 most-broken controls (background, spacing, color, typography, border, visibility)
- Session 2: Add the device toggle + the 8 layout/sizing controls
- Session 3: Polish, presets, test on live

Done is when a non-technical user can open the S-8 panel, click any field, and immediately know what to do.
