feat(wordpress): adiciona elementor-v4-visual-editor (editor visual V4)

Adaptado de jainshwetank/elementor-pro-designer-skill (MIT) - painel
General/Style/Interactions, Class Manager, Variables Manager, breakpoints,
padroes de layout e troubleshooting para o editor visual Elementor Pro V4.
Complementa emcp-page-building (mesma versao Elementor, mas via MCP/API).
This commit is contained in:
Claude Code
2026-08-19 03:50:30 +01:00
parent 4a55d51329
commit 7363300a7f
4 changed files with 545 additions and 0 deletions
@@ -0,0 +1,131 @@
# Padrões de Layout — Elementor V4
Fonte: adaptado de jainshwetank/elementor-pro-designer-skill (MIT). Sequências de instrução de painel testadas em produção — copiar e adaptar.
## Padrão: secção full-height com elemento pinado ao fundo
Caso de uso: heros, ecrãs de abertura com indicador de scroll pinado no fundo.
```
Flexbox "Section Wrap"
CLASSES: [a tua classe de secção]
STYLE > Layout > Direction: Column
STYLE > Layout > Align items: center
STYLE > Size > Height: 100vh ou 90vh ← LOCAL
├── Flexbox "Content"
│ STYLE > Layout > Justify: center
│ STYLE > Layout > Align: center
│ STYLE > Flex child > Flex Size: custom (grow 1) ← LOCAL
│ └── [Headings, CTAs, etc.]
│
└── [Indicador de scroll ou elemento de fundo]
STYLE > Spacing > Margin bottom: [variável de spacing] ← LOCAL
```
Chave: usar `Flex child > Flex Size: grow 1` na área de conteúdo, não uma altura fixa. O elemento de fundo pina naturalmente por ser o último flex child.
## Padrão: layout de duas colunas
Caso de uso: imagem + texto, métrica + descrição, qualquer arranjo lado a lado.
```
Flexbox "Row"
STYLE > Layout > Direction: Row
STYLE > Layout > Align items: center
STYLE > Layout > Gap, Column: [variável de spacing] ← LOCAL
├── Flexbox "Left Column"
│ STYLE > Flex child > Flex Size: custom (grow 1, shrink 1, basis 0%) ← LOCAL
│
└── Flexbox "Right Column"
STYLE > Flex child > Flex Size: custom (grow 1, shrink 1, basis 0%) ← LOCAL
```
Para colunas desiguais (ex. 60/40): basis a `60%` e `40%` respectivamente. No breakpoint Phone: mudar Direction para Column para empilhar.
## Padrão: imagem em moldura
Caso de uso: screenshots, mockups, qualquer imagem que precise de dimensionamento contido.
```
Flexbox "Frame"
STYLE > Size > Width: [px ou % específico] ← LOCAL
STYLE > Size > Aspect Ratio: [conforme o conteúdo — 16/10, 4/3, etc.] ← LOCAL
STYLE > Border > Radius: 4px ← LOCAL
STYLE > Size > Overflow: hidden ← LOCAL
└── Image
STYLE > Size > Width: 100%, Height: 100% ← LOCAL
STYLE > Size > Object fit: cover ← LOCAL
```
Importante: o aspect ratio deve servir o conteúdo. Não forçar enquadramento paisagem em conteúdo retrato (ex. screenshots de telemóvel, UI de app alta) — deixar o conteúdo ditar a forma da moldura.
## Padrão: cabeçalho de passo/secção
Caso de uso: cabeçalhos de secção numerados que comunicam hierarquia.
```
Flexbox "Step Header"
STYLE > Layout > Direction: Column
STYLE > Layout > Gap, Row: [variável de spacing pequena] ← LOCAL
├── Heading "Number" (ex. "01")
│ CLASSES: [a tua classe display/muted]
│ STYLE > Typography > Size: 72px ← LOCAL
│ STYLE > Typography > Weight: 200 ← LOCAL
│ STYLE > Effects > Opacity: 6% ← LOCAL
│
├── Heading "Label" (ex. "Step 1")
│ CLASSES: [a tua classe overline/label]
│
└── Heading "Title" (ex. "O padrão")
CLASSES: [a tua classe h2]
```
O número fantasma (opacity 6%) cria profundidade sem competir com o título.
## Padrão: fundos de secção alternados
Caso de uso: ritmo visual entre secções de conteúdo.
```
Secção A: sem background (herda o background do body)
Secção B: STYLE > Background > Color: [variável de bg secundária] ← LOCAL
Secção C: sem background (herda)
```
Nunca alternar com cores fixas — usar sempre variáveis para o dark mode funcionar.
## Padrão: secção centrada com largura de texto limitada
Caso de uso: secções de texto longo onde o comprimento de linha precisa de limite para legibilidade.
```
Flexbox "Section"
STYLE > Layout > Direction: Column
STYLE > Layout > Align items: center
STYLE > Spacing > Padding [T/B]: [variável de spacing grande]
└── Flexbox "Content"
STYLE > Size > Max width: 640px ← LOCAL
STYLE > Layout > Direction: Column
STYLE > Layout > Gap, Row: [variável de spacing média]
└── [Parágrafos, headings]
```
Aplicar max-width no wrapper de conteúdo interno, não na secção — a secção mantém-se full-width.
## Padrão: separador horizontal
Caso de uso: separação visual dentro de uma secção (não entre secções).
```
Div block "Divider"
STYLE > Size > Width: 100%, Height: 1px ← LOCAL
STYLE > Background > Color: [variável border/muted] ← LOCAL
STYLE > Spacing > Margin [T/B]: [variável de spacing] ← LOCAL
```
Usar um Div block, não o widget Divider — mais controlo, sistema de classes consistente.
@@ -0,0 +1,145 @@
# Referência de Painel — Elementor V4
Fonte: adaptado de jainshwetank/elementor-pro-designer-skill (MIT). Termos de campo mantidos em inglês (interface real do editor).
## Painel de widget: 3 tabs
Todo widget em V4 tem exactamente três tabs: **General**, **Style**, **Interactions**.
### Tab 1: General
- **HTML Tag** — Div / Section / Header / Footer / Main / Article / Nav / Aside
- **Link** — botão (+) para adicionar
- **ID** — campo de texto (anchor links ou hooks JS; deixar vazio caso contrário)
- **Attributes** — botão (+) para atributos `data-*` custom (ex. `data-theme-toggle`)
- **Display Conditions** — só Elementor Pro; mostrar/esconder por role, URL, data, etc.
### Tab 2: Style
Propriedades listadas de cima a baixo pela ordem real no painel.
**Classes** — topo do tab Style. Escrever nome de classe para aplicar do Class Manager. Várias classes empilham (separadas por espaço). Badge "local" = override de instância. Badge de classe = propriedade vinda da classe global.
**Layout**
- Display: `Block` / `Flex` (omissão) / `In-blk` / `None` / `Inline-flex`
- Direction (só Flex): `Row` (omissão) / `Column` / `Row reversed` / `Column reversed`
- Justify content: flex-start / center / flex-end / space-between / space-around / space-evenly
- Align items: flex-start / center / flex-end / stretch
- Gap: Column gap (px) + Row gap (px), toggle de link para sincronizar
- Wrap: nowrap / wrap / wrap-reverse
Sub-secção Flex child (visível quando o elemento está dentro de um pai Flex):
- Align self: auto / flex-start / center / flex-end / stretch
- Order: inteiro
- Flex Size: Fill space (grow 1) / Fit content / Fixed / Custom (grow + shrink + basis)
**Spacing**
- Margin: T/R/B/L, toggle de link, unidades px/%/vw/vh/em/rem
- Padding: T/R/B/L, toggle de link, mesmas unidades
- Nota: alguns widgets V4 têm **padding por omissão de 10px** — verificar sempre e definir a 0 se não pretendido.
**Size**
- Width, Height, Min width, Min height, Max width, Max height (px/%/vw/vh/em/rem)
- Overflow: visible / hidden / auto / scroll
- (Show more): Aspect Ratio, Object fit (cover/contain/fill/none)
**Position**
- Position: default / relative / absolute / fixed / sticky
- Inset (top/right/bottom/left) aparece quando não-default
- Z-index, Anchor offset (para sticky)
**Typography**
- Font family — picker; usar variable picker (ƒ) para variável de fonte
- Font weight: 100–900
- Font size + unidade — variable picker (ƒ) para variável de tamanho ou valor clamp
- Text align: left/center/right/justify
- Text color — picker; variable picker (ƒ) para variável de cor
- (Show more): Line height, Letter spacing, Word spacing, Text decoration, Text transform, Direction (LTR/RTL), Font style, Text stroke
**Background**
- Color — picker; variable picker (ƒ)
- Overlay (+): gradiente ou imagem
- Clipping: text / content-box / border-box / padding-box
**Border**
- Width: T/R/B/L ou todos, toggle de link
- Color — picker; variable picker (ƒ)
- Type: none/solid/dashed/dotted/double/groove/ridge
- Radius: TL/TR/BR/BL, toggle de link
**Effects**
- Blend mode, Opacity (0–100%)
- Box shadow (+): cor, X, Y, blur, spread, toggle inset
- Transform (+): rotate, scale, translate, skew
- Transitions (+): propriedade, duração, timing, delay
- Filters (+): blur, brightness, contrast, grayscale, hue-rotate, invert, saturate, sepia
- Backdrop filters (+): mesmas opções, aplicadas ao fundo atrás do elemento
**Custom CSS** — editor de código no fundo do tab Style. **Deixar sempre vazio.** Usar classes e definições de painel em vez disso.
### Tab 3: Interactions
Botão (+) no topo. Várias interactions podem empilhar-se num elemento.
- **Trigger**: Page load / Scroll into view
- **Effect**: Fade / Slide / Scale
- **Type**: In / Out
- **Direction**: Up / Down / Left / Right
- **Duration**: 0/100/200/300/400/500/750/1000/1250/1500 ms
- **Delay**: mesma escala
- **Preview**: botão ▶
- **Delete**: ✕
## Widgets atómicos (V4 — usar estes)
| Widget | Propósito | Substitui (V3) |
|---|---|---|
| Flexbox | Container de layout com flex | Container |
| Div block | Bloco genérico não-flex | Inner Container |
| Heading | `<h1>`–`<h6>` | Heading (Basic) |
| Paragraph | Texto corpo/rich text | Text Editor (Basic) |
| Image | Imagem com object-fit | Image (Basic) |
| Button | Botão CTA | Button (Basic) |
| SVG | SVG inline | — |
| Divider | Linha `<hr>` | Divider (Basic) |
| YouTube | Vídeo embed | Video (Basic) |
| Tabs | Conteúdo em tabs | — |
**Correspondência com `emcp-page-building`:** estes 10 widgets atómicos mapeiam directamente para as tools MCP `add-flexbox`/`add-div-block`/`add-atomic-heading`/`add-atomic-paragraph`/`add-atomic-image`/`add-atomic-button`/`add-atomic-svg`/`add-atomic-divider`/`add-atomic-youtube` — confirmado ao vivo nessa skill. "Tabs" não tem tool de conveniência própria confirmada; usar `add-atomic-widget` genérico.
## Widgets legacy (V3 — evitar em construções V4 novas)
Container, Inner Container, Text Editor, Spacer, Google Maps. Continuam a existir por compatibilidade. Não usar em construções V4 novas — mas ver `emcp-page-building` para os casos em que um widget legacy é mesmo necessário (terceiros sem versão atómica: ElementsKit, PowerPack, etc.).
## Variables Manager
**Acesso:** ao editar um campo de cor/tamanho no tab Style, clicar no ícone ƒ (variable picker), depois **+** para criar uma variável nova. Acesso directo: ícone ƒ → engrenagem (⚙) abre o Variables Manager completo.
Variáveis são CSS custom properties. O Elementor guarda-as com prefixo `--`, logo uma variável `color_accent` referencia-se em código como `var(--color_accent)`.
**Convenção de nomes** (underscores como separador):
```
color_accent → cor de destaque da marca
color_primary → cor primária de texto/marca
color_bg-primary → cores de fundo/texto/borda
spacing_md → padding, margin, gap
font_heading → família de fonte
size_section-pad → spacing composto para secções
```
**`clamp()` para variáveis responsivas** — definir valores fluidos no Variables Manager para escalar sem overrides por breakpoint:
```css
clamp(2rem, 5vw, 4rem) /* tamanho de fonte que escala de 2rem (mobile) a 4rem (desktop) */
clamp(1rem, 3vw, 2rem) /* spacing que escala de 1rem a 2rem */
```
Escrever a expressão clamp directamente como valor da variável. Aplicar a tamanhos de fonte, padding de secção e valores de gap resolve a maior parte da responsividade num único sítio.
## Class Manager
**Acesso:** tab Style → campo Classes → escrever nome de classe → link "Manage Classes", ou via Elementor site settings.
**O que uma classe guarda:** múltiplas propriedades, cada uma podendo referenciar uma variável. Exemplo: uma classe `t-body` pode definir font-family (via `var(--font_body)`), font-size (via `var(--size_body)`), line-height (1.55) e color (via `var(--color_text-primary)`) — tudo numa classe.
**Quatro estados por classe:** 1. Normal (omissão) · 2. Hover (mouse por cima) · 3. Focus (foco de teclado) · 4. Active (pressionado). Definir cada estado conforme necessário; Hover é o mais usado além de Normal; deixar vazio se não houver mudança nesse estado.
**Badge de classe vs local:** propriedade da classe aplicada e não sobreposta → badge de classe. Override de uma propriedade da classe para um elemento específico → badge "local" (não altera a classe em si, é override de instância).
@@ -0,0 +1,108 @@
# Troubleshooting — Elementor V4
Fonte: adaptado de jainshwetank/elementor-pro-designer-skill (MIT). Sintomas, causas e correcções para problemas comuns do editor visual V4.
## Problemas de layout
**Elementos não empilham verticalmente dentro de um Flexbox**
- Verificar Direction — tem de estar ↓ (column), não → (row).
- Se uma classe está a definir a direction, sobrepor localmente ou rever a classe.
**Flex child não preenche a altura restante**
- Definir Flex child > Flex Size: Custom → Grow: 1, Shrink: 0, Basis: 0%.
- O pai precisa de altura definida (vh, px, ou ele próprio flex) para o grow funcionar.
- Nunca usar `height: 100%` num flex child — usar grow.
**Duas colunas a empilhar verticalmente em desktop**
- Direction do Flexbox pai tem de ser → (row), não ↓ (column).
- Se uma classe força column, sobrepor localmente no breakpoint desktop.
**Gap não aparece entre elementos**
- Gap só funciona em pais Flexbox. Se o pai é um Div block (não-flex), gap não tem efeito.
- Solução: mudar o pai para Flexbox, ou usar Spacing > Margin nos filhos individuais.
**Elemento a fazer overflow do pai**
- Definir no pai: Size > Overflow: hidden.
- Verificar se uma width/min-width fixa no filho excede o pai.
**Elemento sticky não fica sticky**
- Position tem de estar definido como Sticky no próprio elemento.
- O pai não pode ter `overflow: hidden` — isso quebra o sticky.
- Anchor offset controla a que distância do topo o elemento gruda.
## Problemas de espaçamento
**Padding não aplica simetricamente**
- Verificar se o toggle de link (ícone de corrente) está activo — se não, T/R/B/L são independentes.
- Verificar se uma classe está a definir padding conflituoso — o badge "local" aparece se for override.
**Margem entre elementos é irregular**
- Se usares margin nos filhos, os gaps compõem-se entre alguns elementos.
- Solução: remover margens dos filhos, usar Gap no Flexbox pai. Margem no filho só para espaçamento irregular pontual.
## Problemas de tipografia
**Tamanho de fonte não muda**
- Uma classe pode estar a definir o tamanho e estás a editar um override local que não tem efeito.
- Verificar se o campo Typography > Font size mostra badge de classe ou badge "local".
- Se badge de classe: mudar a classe no Class Manager, ou sobrepor localmente.
**Cor do texto não corresponde à variável**
- Confirmar que o campo de cor mostra o nome da variável, não um hex.
- Se mostrar hex: abrir o color picker, seleccionar o ícone de variável (ƒ), escolher a variável.
**Line height demasiado apertado ou solto**
- Line height está escondido em Style > Typography > Show more.
- Texto corpo: 1.5–1.6 é standard. Headings: 1.1–1.2 é standard.
## Problemas de dark mode
**Dark mode não aplica**
- Verificar que o snippet Design Tokens contém overrides `[data-theme="dark"]`.
- Verificar que o botão de toggle tem o atributo `data-theme-toggle` no tab General → Attributes.
- Verificar que o snippet Dark Mode Toggle está activo e na posição footer.
- Abrir DevTools e confirmar que o elemento `html` tem o atributo `data-theme="dark"` depois de clicar no toggle.
**Alguns elementos não mudam no dark mode**
- Só elementos a usar variáveis CSS mudam. Cores hex fixas não mudam.
- Localizar o elemento, verificar cada campo de cor — substituir hex por variável apropriada.
**Flash do tema errado ao carregar a página (FOUC)**
- O snippet Dark Mode Toggle lê o localStorage ao carregar, mas o snippet FOUC pode atrasar a visibilidade.
- Garantir que o atributo `data-theme` é aplicado antes de `visibility: visible` disparar.
- Solução: mover a leitura do localStorage para um `<script>` inline no `<head>` (antes do snippet FOUC disparar).
## Problemas de interactions
**Animação não dispara**
- Trigger tem de ser "Scroll into view" para reveals por scroll.
- Testar fazendo scroll do elemento para fora e depois de volta.
- Se a página carregou com o elemento já visível, "Scroll into view" nunca dispara — usar "Page load" para elementos acima da dobra.
**Animação a disparar cedo demais / elemento visível antes da animação**
- A direction "Out" (Fade Out, Slide Out) é para animações de saída. Provavelmente queres "In".
- Se elementos estão visíveis antes do scroll, verificar se uma animação anterior os deixou num estado visível.
**Várias animações no mesmo elemento em conflito**
- Verificar o tab Interactions — empilha. Se houver uma animação residual de testes, apagar (botão ✕).
- Duas "Fade In" no mesmo elemento disparam ambas e podem entrar em conflito.
**Interaction não aparece no tab Interactions**
- O tab Interactions é o Tab 3 (não Style, não General).
- Só disponível em elementos Elementor V4 — não em widgets legacy V3.
## Problemas de Custom Code
**Snippet Custom Code não aplica**
- Verificar se o snippet está Active (toggle na lista de snippets).
- Verificar a Location: `<head>` para CSS, footer para JS.
- Verificar erros de sintaxe — um `;` em falta parte o snippet inteiro.
**Variável CSS não resolve**
- Nomes de variável em Custom Code usam prefixo `--`: `var(--color_accent)`.
- Confirmar que a variável está definida em `:root` no snippet Design Tokens.
- O Elementor acrescenta `--` automaticamente às variáveis do Variables Manager, mas snippets Custom Code têm de usar a sintaxe completa `var(--nome)`.
**Snippet Design Tokens a crescer demasiado**
- Só variáveis de cor e mapeamentos classe-para-cor pertencem aqui.
- Se estiveres a acrescentar regras de layout, animações ou estilos de componente — mover para um snippet novo e nomeado.