Generate WordPress Gutenberg blocks using Greenshift/GreenLight plugin. Use when user asks to create WordPress sections, blocks, layouts, hero sections, galleries, or any Gutenberg element. Triggers on keywords: wordpress, gutenberg, greenshift, section, block, layout, hero, gallery, columns, element.
/plugin marketplace add vcode-sh/vibe-tools/plugin install greenshift-blocks@vibe-toolsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
docs/00-index.mddocs/01-core-structure.mddocs/02-attributes.mddocs/03-layouts.mddocs/04-styling-advanced.mddocs/05-animations.mddocs/06-slider.mddocs/07-dynamic-content.mddocs/08-variations.mddocs/09-css-variables.mddocs/10-scripts.mddocs/11-charts.mddocs/12-migration-rules.mdreference.mdtemplates/card-grid.htmltemplates/cta-banner.htmltemplates/faq-section.htmltemplates/features-grid.htmltemplates/footer.htmltemplates/hero-section.htmlGenerate production-ready WordPress Gutenberg blocks using Greenshift/GreenLight Element block system. All output is HTML with JSON parameters in block comments - ready to paste directly into WordPress Gutenberg code editor.
Detailed documentation is split into modular files in the docs/ directory:
| File | Topic |
|---|---|
docs/00-index.md | Navigation index |
docs/01-core-structure.md | Block format, JSON parameters, content types, styleAttributes |
docs/02-attributes.md | HTML attributes, links, images, forms, icons |
docs/03-layouts.md | Sections, columns, flexbox configurations |
docs/04-styling-advanced.md | Local classes (dynamicGClasses), gradients, background images, parallax |
docs/05-animations.md | AOS animations, CSS keyframes, scroll animations |
docs/06-slider.md | Swiper slider block configuration |
docs/07-dynamic-content.md | Dynamic text, query grids, placeholders |
docs/08-variations.md | Accordion, tabs, counter, countdown, etc. |
docs/09-css-variables.md | All CSS variables (fonts, spacing, shadows, etc.) |
docs/10-scripts.md | Custom JavaScript and GSAP integration |
docs/11-charts.md | ApexCharts integration |
docs/12-migration-rules.md | CRITICAL - Typography stripping, semantic headings, minimal styling |
Read relevant docs files when you need detailed information on specific topics.
IMPORTANT: Always read docs/12-migration-rules.md when migrating or cloning blocks - it contains critical rules about what styles to REMOVE.
Every Greenshift element follows this pattern:
<!-- wp:greenshift-blocks/element {JSON Parameters} -->
<html_tag class="optional classes" ...attributes>
<!-- Inner content -->
</html_tag>
<!-- /wp:greenshift-blocks/element -->
Block IDs: Unique id starting with gsbp- + 7 alphanumeric chars (e.g., gsbp-b3c761b). localId must be identical to id.
Content Types (type parameter):
"text": Text-only blocks - requires textContent with duplicated text"inner": Container blocks - wrap plain text in <span> element blocks"no": Empty/spacer elements"chart": ApexChartsStyling (styleAttributes):
style="..." attributesbackgroundColor, paddingTop)["desktop", "tablet", "mobile_landscape", "mobile_portrait"]["10px"] applies to all breakpointsbackgroundColor_hover, color_focusstyleAttributes exists, add localId to HTML class attributeHTML Tags: Default is div. Prefer tag: "a" over tag: "button" for buttons (except forms).
Images: Always loading="lazy". Use https://placehold.co/WIDTHxHEIGHT. When using originalWidth and originalHeight in JSON, you MUST also add matching width and height HTML attributes to the <img> tag.
Links: linkNewWindow: true = target="_blank" + auto rel="noopener"
Column Children with Padding: Always add boxSizing: ["border-box"] to column children that have padding. Without this, padding adds to width and causes columns to wrap unexpectedly. See docs/03-layouts.md for details.
See docs/01-core-structure.md and docs/02-attributes.md for full details.
When generating or migrating blocks, apply minimal styling intervention. Let the WordPress theme handle defaults.
See docs/12-migration-rules.md for comprehensive migration-specific rules.
| Avoid | Why |
|---|---|
Adding fontSize to headings (h1-h6) | Theme typography handles heading sizes |
Adding color to headings/paragraphs | Theme colors cascade from settings |
Adding fontWeight to headings | Theme defines heading weights |
Adding fontWeight: ["400"] anywhere | It's the default - remove it |
Adding lineHeight to headings | Theme handles heading line-heights |
| Setting responsive fontSize on headings | Theme's heading styles are already responsive |
| Using generic background colors | Use theme palette variables (palette-color-6, etc.) |
Headings (h1, h2, h3, h4, h5, h6) - NEVER SET:
fontSize - theme handles heading sizes (even responsive ones)fontWeight - theme handles heading weightscolor - theme handles text colors (unless on dark background)lineHeight - theme handles heading line-heightsHeadings - OKAY TO SET:
marginTop, marginBottom - for spacing controltextAlign - for layout/centeringWRONG - Over-styled heading:
{
"tag": "h2",
"styleAttributes": {
"fontSize": ["3rem", "2.7rem"],
"fontWeight": ["700"],
"lineHeight": ["1.2"]
}
}
CORRECT - Minimal heading:
{
"tag": "h2",
"styleAttributes": {
"marginBottom": ["1rem"],
"textAlign": ["center"]
}
}
Paragraphs and text - NEVER SET:
color - unless on dark/colored backgroundfontWeight: ["400"] or fontWeight: ["normal"] - these are defaultslineHeight - unless custom fontSize requires adjustmentParagraphs and text - OKAY TO SET:
fontSize - ONLY for intentional accent/lead text (e.g., ["1.2rem"])fontFamily - for specific font choicesfontWeight: ["700"] - for intentionally bold body textmaxWidth - for constraining text widthException - Text on dark backgrounds: When text is over a dark background (hero overlays, dark sections, card overlays):
"color":["var(--wp--preset--color--white, #ffffff)"]"color":["rgba(255,255,255,0.9)"]Use proper HTML heading levels based on content structure:
h1 - Page title (usually in theme header)
h2 - Main section titles (one per section)
h3 - Subsection/card titles
h4 - Minor headings within cards/subsections
Example - Step Cards:
h2h3h4DON'T: Use multiple h2s in same section or h3 for minor card headings.
WRONG - Generic variables:
"backgroundColor": ["var(--wp--preset--color--white, #ffffff)"]
"backgroundColor": ["var(--wp--preset--color--light-grey, #f8f8f8)"]
CORRECT - Theme palette:
"backgroundColor": ["var(--wp--preset--color--palette-color-6, var(--theme-palette-color-6, #f5f5f4))"]
"backgroundColor": ["var(--wp--preset--color--palette-color-7, var(--theme-palette-color-7, #fafaf9))"]
"backgroundColor": ["var(--wp--preset--color--palette-color-8, var(--theme-palette-color-8, #fffffe))"]
Palette colors (6, 7, 8) adapt to user's theme settings. Generic colors override theme customization.
WRONG - Over-styled:
{
"styleAttributes": {
"fontSize": ["16px"],
"fontWeight": ["400"],
"lineHeight": ["1.5"],
"color": ["#333333"],
"marginBottom": ["20px"]
}
}
CORRECT - Minimal:
{
"styleAttributes": {
"marginBottom": ["var(--wp--preset--spacing--50)"]
}
}
Or even better - no styleAttributes at all if theme defaults are acceptable.
For column gaps, use CSS variables:
{
"styleAttributes": {
"columnGap": ["var(--wp--preset--spacing--60, 2rem)"],
"rowGap": ["var(--wp--preset--spacing--60, 2rem)"]
}
}
AVOID hardcoded gaps like "columnGap": ["25px"] unless specifically required.
When migrating or cloning:
Always use greenshift-blocks/element for most content. Convert old blocks to GreenLight Element:
| Old Block (AVOID) | Replace With |
|---|---|
greenshift-blocks/row | greenshift-blocks/element with tag:"section", align:"full" |
greenshift-blocks/row-column | greenshift-blocks/element with type:"inner" or remove entirely |
greenshift-blocks/heading | greenshift-blocks/element with tag:"h1/h2/h3", textContent |
These specialized blocks are acceptable:
greenshift-blocks/element - GreenLight Element (primary block)greenshift-blocks/swiper - Slider/carouselgreenshift-blocks/querygrid - Query loop for postsgreenshift-blocks/dynamic-post-image - Dynamic featured imagegreenshift-blocks/dynamic-post-title - Dynamic post titlegreenshift-blocks/meta - Post meta dataWRONG (old greenshift-blocks/heading):
<!-- wp:greenshift-blocks/heading {"id":"gsbp-xxx","headingContent":"Title","spacing":{...},"typography":{...}} -->
<h2 id="gspb_heading-id-gsbp-xxx" class="gspb_heading gspb_heading-id-gsbp-xxx">Title</h2>
<!-- /wp:greenshift-blocks/heading -->
CORRECT (GreenLight Element - minimal):
<!-- wp:greenshift-blocks/element {"id":"gsbp-xxx","textContent":"Title","tag":"h2","localId":"gsbp-xxx","styleAttributes":{"marginBottom":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dspacing\u002d\u002d50, 1.5rem)"]}} -->
<h2 class="gsbp-xxx">Title</h2>
<!-- /wp:greenshift-blocks/element -->
Key differences:
textContent instead of headingContenttag:"h2" instead of default divmarginBottom if spacing control neededgsbp-xxx not gspb_heading gspb_heading-id-gsbp-xxxid attribute in HTML, only classSVG content inside the JSON icon.icon.svg parameter MUST use Unicode escape sequences, not raw HTML or escaped quotes.
| Character | Escape Sequence |
|---|---|
< | \u003c |
> | \u003e |
" | \u0022 |
WRONG:
"icon":{"icon":{"svg":"<svg viewBox=\"0 0 24 24\"><path d=\"M8 12l2 2\"/></svg>"},...}
CORRECT:
"icon":{"icon":{"svg":"\u003csvg viewBox=\u00220 0 24 24\u0022\u003e\u003cpath d=\u0022M8 12l2 2\u0022/\u003e\u003c/svg\u003e"},...}
When creating cards with images that have rounded corners INSIDE the card (with visible margin/padding around them):
Card Wrapper (white bg, border-radius: 15px, overflow: hidden)
├── Image Container (padding: 8px top/left/right, 0px bottom)
│ └── Image (border-radius: 10px on ALL 4 corners, object-fit: cover)
└── Footer/Label Area (padding for content)
overflow: hidden + larger border-radius (e.g., 15px)paddingBottom: 0px (no gap to footer)"styleAttributes": {
"width": ["100%"],
"aspectRatio": ["16/10"],
"objectFit": ["cover"],
"borderTopLeftRadius": ["var(--wp--custom--border-radius--small, 10px)"],
"borderTopRightRadius": ["var(--wp--custom--border-radius--small, 10px)"],
"borderBottomLeftRadius": ["var(--wp--custom--border-radius--small, 10px)"],
"borderBottomRightRadius": ["var(--wp--custom--border-radius--small, 10px)"],
"borderRadiusLink_Extra": true
}
var(--wp--preset--font-size--mini, 11px)
var(--wp--preset--font-size--xs, 0.85rem)
var(--wp--preset--font-size--s, 1rem)
var(--wp--preset--font-size--m, 1.35rem)
var(--wp--preset--font-size--l, 1.55rem)
var(--wp--preset--font-size--xl, clamp(1.6rem, 2.75vw, 1.9rem))
var(--wp--preset--font-size--grand, clamp(2.2rem, 4vw, 2.8rem))
var(--wp--preset--font-size--giga, clamp(3rem, 5vw, 4.5rem))
var(--wp--preset--font-size--giant, clamp(3.2rem, 6.2vw, 6.5rem))
var(--wp--preset--spacing--40, 1rem)
var(--wp--preset--spacing--50, 1.5rem)
var(--wp--preset--spacing--60, 2.25rem)
var(--wp--preset--spacing--70, 3.38rem)
var(--wp--preset--spacing--80, 5.06rem)
var(--wp--custom--border-radius--mini, 5px)
var(--wp--custom--border-radius--small, 10px)
var(--wp--custom--border-radius--medium, 15px)
var(--wp--custom--border-radius--large, 20px)
var(--wp--preset--shadow--soft, 0px 15px 30px 0px rgba(119, 123, 146, 0.1))
var(--wp--preset--shadow--elegant, 0px 5px 23px 0px rgba(188, 207, 219, 0.35))
var(--wp--custom--transition--ease, all 0.5s ease)
var(--wp--custom--transition--smooth, all 1s cubic-bezier(0.66,0,0.34,1))
See docs/09-css-variables.md for complete list.
ALWAYS wrap full pages in a single container. This is critical for controlling spacing.
Why Page Wrapper is essential:
<!-- wp:greenshift-blocks/element {"id":"gsbp-page001","type":"inner","localId":"gsbp-page001","align":"full","styleAttributes":{"marginBlockStart":["0px"]},"metadata":{"name":"Page Wrapper"}} -->
<div class="gsbp-page001 alignfull">
<!-- All sections go here -->
</div>
<!-- /wp:greenshift-blocks/element -->
Key points:
align:"full" in JSON + alignfull in HTML classmarginBlockStart:["0px"] removes top margin forced by themes<!-- wp:greenshift-blocks/element {"id":"gsbp-XXXXXXX","tag":"section","type":"inner","localId":"gsbp-XXXXXXX","align":"full","styleAttributes":{"display":["flex"],"justifyContent":["center"],"flexDirection":["column"],"alignItems":["center"],"paddingRight":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dspacing\u002d\u002dside, min(3vw, 20px))"],"paddingLeft":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dspacing\u002d\u002dside, min(3vw, 20px))"],"paddingTop":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dspacing\u002d\u002d80, 5rem)"],"paddingBottom":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dspacing\u002d\u002d80, 5rem)"],"marginBlockStart":["0px"]},"isVariation":"contentwrapper"} -->
<section class="gsbp-XXXXXXX alignfull">
<!-- Content Area -->
</section>
<!-- /wp:greenshift-blocks/element -->
IMPORTANT: Use content-size (not wide-size) for content width:
<!-- wp:greenshift-blocks/element {"id":"gsbp-XXXXXXX","type":"inner","localId":"gsbp-XXXXXXX","styleAttributes":{"maxWidth":["100%"],"width":["var(\u002d\u002dwp\u002d\u002dstyle\u002d\u002dglobal\u002d\u002dcontent-size, 1290px)"]},"isVariation":"nocolumncontent","metadata":{"name":"Content Area"}} -->
<div class="gsbp-XXXXXXX">
<!-- Inner content -->
</div>
<!-- /wp:greenshift-blocks/element -->
<!-- wp:greenshift-blocks/element {"id":"gsbp-XXXXXXX","type":"inner","localId":"gsbp-XXXXXXX","styleAttributes":{"display":["flex"],"flexColumns_Extra":2,"flexWidths_Extra":{"desktop":{"name":"50/50","widths":[50,50]},"tablet":{"name":"50/50","widths":[50,50]},"mobile":{"name":"100/100","widths":[100,100]}},"flexDirection":["row"],"columnGap":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dspacing\u002d\u002d60, 2rem)"],"rowGap":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dspacing\u002d\u002d60, 2rem)"],"flexWrap":["wrap"]},"isVariation":"contentarea"} -->
<div class="gsbp-XXXXXXX">
<!-- Column 1 -->
<!-- Column 2 -->
</div>
<!-- /wp:greenshift-blocks/element -->
See docs/03-layouts.md for more layout patterns.
<!-- wp:greenshift-blocks/element {"id":"gsbp-XXXXXXX","textContent":"Your Heading","tag":"h2","animation":{"duration":800,"easing":"ease","type":"fade-up","onlyonce":true},"localId":"gsbp-XXXXXXX","styleAttributes":{"marginBottom":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dspacing\u002d\u002d50, 1.5rem)"]}} -->
<h2 data-aos="fade-up" data-aos-easing="ease" data-aos-duration="800" data-aos-once="true" class="gsbp-XXXXXXX">Your Heading</h2>
<!-- /wp:greenshift-blocks/element -->
Note: No fontSize or color on heading - theme handles typography. Only marginBottom for spacing.
See docs/05-animations.md for all animation options.
<!-- wp:greenshift-blocks/element {"id":"gsbp-XXXXXXX","textContent":"Click Here","tag":"a","localId":"gsbp-XXXXXXX","href":"#","styleAttributes":{"display":["inline-flex"],"paddingTop":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dbutton\u002d\u002dspacing\u002d\u002dvertical, 1rem)"],"paddingBottom":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dbutton\u002d\u002dspacing\u002d\u002dvertical, 1rem)"],"paddingLeft":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dbutton\u002d\u002dspacing\u002d\u002dhorizontal, 2rem)"],"paddingRight":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dbutton\u002d\u002dspacing\u002d\u002dhorizontal, 2rem)"],"backgroundColor":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dcolor\u002d\u002dprimary, #000)"],"color":["#fff"],"borderRadius":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dborder-radius\u002d\u002dmedium, 15px)"],"textDecoration":["none"],"transition":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dtransition\u002d\u002dease, all 0.5s ease)"],"backgroundColor_hover":["var(\u002d\u002dwp\u002d\u002dpreset\u002d\u002dcolor\u002d\u002dsecondary, #333)"]}} -->
<a class="gsbp-XXXXXXX" href="#">Click Here</a>
<!-- /wp:greenshift-blocks/element -->
<!-- wp:greenshift-blocks/element {"id":"gsbp-XXXXXXX","tag":"img","localId":"gsbp-XXXXXXX","src":"https://placehold.co/800x600","alt":"Description","originalWidth":800,"originalHeight":600,"styleAttributes":{"width":["100%"],"height":["auto"],"objectFit":["cover"],"borderRadius":["var(\u002d\u002dwp\u002d\u002dcustom\u002d\u002dborder-radius\u002d\u002dsmall, 10px)"]}} -->
<img class="gsbp-XXXXXXX" src="https://placehold.co/800x600" alt="Description" width="800" height="600" loading="lazy"/>
<!-- /wp:greenshift-blocks/element -->
isVariation)| Variation | Use Case | Details |
|---|---|---|
"contentwrapper" | Full-width section wrapper | See docs/03-layouts.md |
"nocolumncontent" | Centered content area | See docs/03-layouts.md |
"contentcolumns" / "contentarea" | Column layouts | See docs/03-layouts.md |
"accordion" | Collapsible accordion | See docs/08-variations.md |
"tabs" | Tab interface | See docs/08-variations.md |
"counter" | Animated number counter | See docs/08-variations.md |
"countdown" | Countdown timer | See docs/08-variations.md |
"marquee" | Scrolling marquee | See docs/08-variations.md |
"buttoncomponent" | Styled button | See docs/08-variations.md |
"videolightbox" | Video with lightbox | See docs/08-variations.md |
Available animation.type values:
fade, fade-up, fade-down, fade-left, fade-rightzoom-in, zoom-in-up, zoom-in-down, zoom-outslide-up, slide-down, slide-left, slide-rightflip-up, flip-down, flip-left, flip-rightclip-right, clip-left, clip-up, clip-downAnimation parameters: duration (ms), delay (ms), easing, onlyonce (boolean)
See docs/05-animations.md for keyframe animations and scroll-linked animations.
For blocks displaying WordPress data (posts, users, taxonomies):
<!-- wp:greenshift-blocks/element {"id":"gsbp-xxx","textContent":"<dynamictext></dynamictext>","dynamictext":{"dynamicEnable":true,"dynamicType":"postdata","dynamicSource":"latest_item","dynamicPostData":"post_title"},"localId":"gsbp-xxx"} -->
<div class="gsbp-xxx"><dynamictext></dynamictext></div>
<!-- /wp:greenshift-blocks/element -->
See docs/07-dynamic-content.md for all dynamic types and query grids.
Use greenshift-blocks/swiper for image galleries and hero sliders.
CRITICAL: For image gallery slides, use greenshift-blocks/element with tag:"img" inside slider-content-zone. Do NOT put images directly in slider-image-wrapper.
See docs/06-slider.md for complete slider documentation and correct structure.
Before generating output, verify these visual details from the reference design:
object-fit: cover) or maintain aspect ratio (object-fit: contain)?originalWidth/originalHeight in JSON → matching width/height in HTMLBefore outputting Greenshift blocks, verify these critical rules:
metadata:{"name":"..."} instead of <!-- Section Name -->align:"full" and <div class="... alignfull">originalWidth/originalHeight in JSON, add matching width/height to HTML <img> tagfill="none" on outer <svg> element (WordPress strips it - put on <path> elements)greenshift-blocks/element blocks in slider-content-zone, NOT direct <img> in slider-image-wrapperimageurl:"" (empty string), add bgContain:falsewp:greenshift-blocks/element (or specialized like swiper, querygrid)metadata:{"name":"..."} for organization.html filesReference templates are in the templates/ directory:
section-wrapper.html - Full-width section wrappertwo-columns.html - Two-column responsive layouthero-section.html - Hero section with backgroundcard-grid.html - Card grid layout