← Unbounce - Classic BuilderCONTENT HISTORY

Update to Unbounce - Classic Builder

Snapshot Oct 28, 2026 · 12:26 UTC · version 1.0.405

Collection source: downloaded plugin package. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.

WHAT CHANGED

Instructions updated for mcp-modernize

Full description — Now says: Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute...

Observed in instructions or declared skills. Runtime behavior has not been tested.

Save Unbounce - Classic Builder and check future changes in Following.

Up to 10 plugins free · no card required.

All fields and original values.

Full description

Before

Sep 30, 2026 · 23:08 UTC

page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Unbounce page, or edit a page that ...

After

Oct 28, 2026 · 12:26 UTC

Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Classic page, or edit a pag...

Skill instructions

Before

Sep 30, 2026 · 23:08 UTC

page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Unbounce page, or edit a page that ...

After

Oct 28, 2026 · 12:26 UTC

Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Classic page, or edit a pag...

Compare saved observations

Download comparison JSON

SKILL.md text changes

− removed · + added

--- before
+++ after
@@ -1,6 +1,6 @@
 ---
 name: mcp-modernize
-description: Rewrite an imported (absolutely-positioned) Unbounce page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Unbounce page, or edit a page that was built in the Unbounce builder — phrasings like "modernize this page", "make my page responsive", "convert my old page", "clean HTML version". Replication-faithful — this is a layout rewrite, never a redesign.
+description: Rewrite an imported (absolutely-positioned) Unbounce Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Classic page, or edit a page that was hand-built in the Unbounce Classic builder — phrasings like "modernize this page", "make my page responsive", "convert my old page", "clean HTML version". Replication-faithful — this is a layout rewrite, never a redesign. Not for AI Builder pages, which stay editable as they are (mcp-ai-builder-authoring).
 requires:
   mcpServers:
     - unbounce-mcp
@@ -101,10 +101,67 @@
 flex/grid present, per-section max-width, overlay columns reserved). Fix
 failures before delivering; never rationalize past a hard stop.
 
+**Step 6b — Carry GA click tracking across.** A Classic page's link clicks are
+tracked by Unbounce's built-in GA link tracker, which keys off builder elements.
+Your rewrite is hand-written `<a>` tags, so that tracker stops attaching and the
+customer silently loses click data they had before. Preserving it is replication
+fidelity, not a redesign — so include
+[`../mcp-page-authoring/scripts/ga-click-tracking.js`](../mcp-page-authoring/scripts/ga-click-tracking.js)
+as a `scripts` entry (name it e.g. "GA click tracking", placement `body_bottom`).
+Never fork or hand-roll it. It feature-detects `gtag`/`ga` and no-ops on domains
+without the integration, so it is safe to add unconditionally.
+
+**Send it as a `ref`, not a `tag`.** Read the file, `upload` it, and pass the
+`upload://` reference it returns as the entry's `ref` — see
+[Writing a `scripts` entry](../mcp-page-authoring/SKILL.md#writing-a-scripts-entry).
+"Pass its contents verbatim" is not a shape `update_variant_from_html` accepts:
+an entry is a bare `upload://` string, or an object with exactly one of `ref`,
+`src` or `tag`. Handing it the raw JavaScript as a string fails loudly, which is
+fine.
+
+A `tag` is accepted, and what happens next depends on the tag. A bare
+`<script>…</script>` is unwrapped on write and stored exactly as a `ref` would
+be, so it does round-trip. An **attributed** one — `<script type="text/javascript">`
+— is stored verbatim, opening tag and all, and comes back as a `tag` whose text
+starts with `<script`. Use `ref` so there is a single shape either skill can
+recognise, and so the entry you re-send later is the one you read.
+
+**Pass back every `scripts` entry the variant already had, plus this one.** Step 7
+has you send a complete `scripts` set, and in that call anything you leave out is
+deleted — so "don't add a second copy" must not become "don't include it". You
+already downloaded the existing entries in Step 2; re-send each one unchanged. If
+you are making no script change at all, omit `scripts` entirely instead, which
+preserves what is there.
+
+**Recognising an entry that already carries this tracking:** its body **contains**
+the line `// Google Analytics click tracking.` — the script is passed verbatim, so
+that string is present in any entry either skill created. Test for the line being
+present, not for the body starting with it: `get_variant` hands a JS-body script
+back as a `ref` you must download, and the `scripts_preserved` / `removed_scripts`
+reports give a `tag` that starts with `<script>`. Step 2 has already downloaded
+every script here, so the bodies are to hand. If one is there, re-send it as-is
+and add nothing; a second copy double-counts every click, which is worse than the
+under-count it was meant to fix and much harder to notice.
+
+The why and the guardrails (never add the GA loader) live in
+[`../mcp-page-authoring/rules/google-analytics.md`](../mcp-page-authoring/rules/google-analytics.md).
+
 **Step 7 — Write back in place and hand over.** `update_variant_from_html` on
 the same variant. It is a TRUE FULL REPLACE: pass the complete artifact set
-(html + all css + all js) every time — anything omitted is dropped. The change
-is staged, never published by you. Hand the user: what you did (one line), the
+(html + all css + all js) every time — anything omitted is dropped. `scripts` is
+the one exception to "every time", and only because omitting the array entirely
+is how you say "change no scripts"; see the paragraph below before you pass it.
+
+**`scripts` deserves its own care.** Passing the array replaces the complete set,
+and a variant can carry entries nobody authored through these tools — an Unbounce
+popup attaches itself as one. Dropping such an entry deletes a customer's popup or
+tracking pixel, and nothing about the rendered page shows it happened. So re-send
+every entry you read in Step 2, or omit `scripts` altogether if you are changing
+none of them (omission preserves them). This is the one place where "pass
+everything" and this skill's promise to _preserve user customizations verbatim_
+can pull apart if you are not deliberate.
+
+The change is staged, never published by you. Hand the user: what you did (one line), the
 `preview_ref` from a fresh `get_variant` (plus the builder preview link from
 `list_page_variants` for the original, so they can compare), the evidence
 summary from the self-check, and any genuine differences — concrete and
@@ -116,7 +173,10 @@
   Nothing added that has no source element — no nav, no sticky header, no hover
   effects the source lacks. Conversion-optimization defaults from
   `mcp-page-authoring` do NOT apply to a rewrite — replication trumps
-  landing-page best practices.
+  landing-page best practices. **One deliberate exception:** the GA
+  click-tracking script in Step 6b. It adds no content and changes nothing a
+  visitor sees; it restores instrumentation the source page already had and the
+  rewrite would otherwise drop. Nothing else earns an exception here.
 - **Every source text string appears verbatim** in the rewrite (whitespace-
   insensitive). Element names, ids, and image filenames are NOT content.
 - **Reuse every asset by its exact URL**, keeping `srcset`/`image-set` and
Full technical diff · 2 changed fields

changed /description

BEFORE
"Rewrite an imported (absolutely-positioned) Unbounce page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Unbounce page, or edit a page that was built in the Unbounce builder — phrasings like \"modernize this page\", \"make my page responsive\", \"convert my old page\", \"clean HTML version\". Replication-faithful — this is a layout rewrite, never a redesign."
AFTER
"Rewrite an imported (absolutely-positioned) Unbounce Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Classic page, or edit a page that was hand-built in the Unbounce Classic builder — phrasings like \"modernize this page\", \"make my page responsive\", \"convert my old page\", \"clean HTML version\". Replication-faithful — this is a layout rewrite, never a redesign. Not for AI Builder pages, which stay editable as they are (mcp-ai-builder-authoring)."

changed /skill_md_contents

BEFORE
"---\nname: mcp-modernize\ndescription: Rewrite an imported (absolutely-positioned) Unbounce page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Unbounce page, or edit a page that was built in the Unbounce builder — phrasings like \"modernize this page\", \"make my page responsive\", \"convert my old page\", \"clean HTML version\". Replication-faithful — this is a layout rewrite, never a redesign.\nrequires:\n  mcpServers:\n    - unbounce-mcp\n---\n\n# Modernizing an Unbounce page (responsive rewrite)\n\nTurn a page built in the Unbounce builder into clean, responsive flexbox/grid\nHTML — **pixel-faithful to the original on desktop, reflowing sensibly on\nmobile**. This is a REPLICATION task with zero creative latitude: same copy,\nsame images, same fonts, same colors, same element counts. The only thing that\nchanges is the layout model (absolute positioning → flex/grid).\n\nThe pipeline is two deliberate stages:\n\n1. **Import** — `create_variant_from_existing_variant` clones the builder-built\n   source into an MCP-managed variant that renders identically (deterministic;\n   every string, image URL, font, and form field lands in the copy verbatim).\n2. **Rewrite** (this skill) — read that copy, restructure its layout to\n   responsive flex/grid, and write it back **in place** with\n   `update_variant_from_html`.\n\nExtraction fidelity is stage 1's job and it is deterministic — never work from\nthe original builder page directly, and never re-derive content from screenshots\nor memory. Your job is only the layout transformation.\n\n## Language with the user\n\nNever say \"modernize\", \"modernization\", \"replica\", or platform-internal terms\nto the user. Their page is fine; say \"make your page responsive\" and \"an\neditable copy of your page\". The result cannot be edited in the Unbounce\nbuilder — all future edits go through MCP tools; say so at handover, and never\nsuggest the builder.\n\n## Workflow\n\n**Step 1 — Resolve the target.** Identify the page (`list_client_pages`) and\nvariant (`list_page_variants`). If the target variant is builder-built (not\nMCP-managed), tell the user in one line what is about to happen — e.g. _\"I'll\ncreate an editable copy of your page, then make that copy responsive — your\noriginal stays untouched\"_ — then run `create_variant_from_existing_variant`\n(no `target_page` ⇒ new page). No further permission ceremony is needed; the\ncopy is additive and safe. Relay any conversion warnings honestly. A\nfixed-width \"autoscale\" source converts fine — the conversion report notes that\nruntime viewport scaling isn't preserved; that is expected and harmless here,\nbecause you rewrite the page responsive from scratch (Step 4), discarding the\nscaling entirely. If the target is already an MCP-managed imported copy, skip\nstraight to Step 2.\n\n**Step 2 — Read the copy.** `get_variant` on the imported variant. Download the\n`html_ref` / `css_refs` sources and any `scripts` entry's `ref` (via `download`, or\n`download_inband` if you cannot run shell commands). This body is the **sole\nsource of truth** for every value: copy strings, image URLs (with their\n`srcset`), `@font-face` blocks, colors, dimensions, form fields, `<ub:dynamic>`\ntags. Never guess a value, never take one from a screenshot, never reconstruct\nfrom memory. If the copy came from an autoscale source, its CSS wraps lengths in\n`calc(<px> * var(--scale, 1))` and it may carry a viewport scale script —\nignore both: read the plain px value (the `* var(--scale)` is the fixed-width\nscaling you are removing) and never copy the scale script into the rewrite. Your\nresponsive layout comes from the Step 3 rows, not these fixed dimensions.\n\n**Step 3 — Get the layout skeleton and fidelity signals.** `get_layout_hints`\non the same variant. It returns, per section: `rows` (element ids clustered\ninto visual rows, left-to-right), per-element geometry,\n`cross_section_overlays` (elements whose vertical span crosses into later\nsections), and `design_width` (the fixed canvas width). **The rows are your\nflex/grid structure.** Do not derive structure from the absolute coordinates\nyourself, and never translate `top`/`left` values through into the rewrite.\nIt also returns measured fidelity signals — `page_defaults` (the page's real\nbase text color and typography), per-section backgrounds, per-element\ncolors/typography/text/image/link inventories, `palette`, `loaded_fonts`,\n`row_stats`, `content_extent`, `hidden_elements`. Those are ground truth:\nauthor from them per [rules/color.md](rules/color.md), never from assumption.\nIf hints come back empty for a variant that plainly has a positioned tree,\nstop and report it (see [rules/verification.md](rules/verification.md)).\n\n**Step 4 — Audit, in writing, before any HTML.** Post a compact audit into the\nconversation (it must survive context compaction): per section — the row\nstructure from hints, the element **counts** per row, every text string\n(verbatim), every image URL + srcset, fonts, colors, form fields\n(name/type/order/options/submit label), interaction states (`:hover`/`:focus`),\nand every cross-section overlay with its pattern (column vs centered). Every\nvalue in your output must trace back to an audit row.\n\n**Step 5 — Write the responsive HTML.** Follow\n[rules/layout.md](rules/layout.md) (section/inner max-width pattern, flex/grid\nfrom hint rows, overlay handling) and\n[rules/replication.md](rules/replication.md) (verbatim preservation). If the\nuser also asked for a change (\"modernize it and swap the headline\"), use\ntwo-pass authoring: pass 1 is a content-identical rewrite, verified; only then\napply their change (see TWO-PASS in rules/replication.md).\n\n**Step 6 — Self-check before writing back.** Run the checklist in\n[rules/verification.md](rules/verification.md) — text walk, count checks, the\nclosure checks against the extracted signals (image-src, link-href, palette,\nfont sets; the WCAG contrast table from [rules/color.md](rules/color.md)), and\nthe hard stops (`position:absolute` budget, zero authored `cbc-*` references,\nflex/grid present, per-section max-width, overlay columns reserved). Fix\nfailures before delivering; never rationalize past a hard stop.\n\n**Step 7 — Write back in place and hand over.** `update_variant_from_html` on\nthe same variant. It is a TRUE FULL REPLACE: pass the complete artifact set\n(html + all css + all js) every time — anything omitted is dropped. The change\nis staged, never published by you. Hand the user: what you did (one line), the\n`preview_ref` from a fresh `get_variant` (plus the builder preview link from\n`list_page_variants` for the original, so they can compare), the evidence\nsummary from the self-check, and any genuine differences — concrete and\nspecific, or \"none\". Publishing, traffic, and goals are the user's call.\n\n## Hard invariants (the load-bearing rules)\n\n- **No creative changes. No additions.** Same typo, same order, same counts.\n  Nothing added that has no source element — no nav, no sticky header, no hover\n  effects the source lacks. Conversion-optimization defaults from\n  `mcp-page-authoring` do NOT apply to a rewrite — replication trumps\n  landing-page best practices.\n- **Every source text string appears verbatim** in the rewrite (whitespace-\n  insensitive). Element names, ids, and image filenames are NOT content.\n- **Reuse every asset by its exact URL**, keeping `srcset`/`image-set` and\n  `background-position`/`size`/`repeat` verbatim. Copy `@font-face` blocks and\n  `<ub:dynamic>` tags through unchanged.\n- **Forms:** plain `<form>` in your output; preserve field names, types, order,\n  options, and the submit label exactly (the server re-wires submission on\n  write). Preserve the hidden form-confirmation overlay (`cfm-*` markup) and\n  its trigger script verbatim if the copy has one.\n- **Preserve user customizations verbatim**: custom-HTML embeds, tracking\n  scripts, hand-applied CSS classes. Flag (don't rewrite) any script selectors\n  that target old ids.\n- **No subagent delegation.** The source must stay in the same context as the\n  build — a subagent without the verbatim source invents copy.\n- **Stay in your lane at delivery**: staged in-place update, no publish, no\n  traffic, no goal changes.\n\nLong-form rules, worked examples, and the catalog of real past failures:\n[rules/replication.md](rules/replication.md) ·\n[rules/layout.md](rules/layout.md) ·\n[rules/color.md](rules/color.md) ·\n[rules/verification.md](rules/verification.md) ·\n[rules/failure-catalog.md](rules/failure-catalog.md)\n"
AFTER
"---\nname: mcp-modernize\ndescription: Rewrite an imported (absolutely-positioned) Unbounce Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Classic page, or edit a page that was hand-built in the Unbounce Classic builder — phrasings like \"modernize this page\", \"make my page responsive\", \"convert my old page\", \"clean HTML version\". Replication-faithful — this is a layout rewrite, never a redesign. Not for AI Builder pages, which stay editable as they are (mcp-ai-builder-authoring).\nrequires:\n  mcpServers:\n    - unbounce-mcp\n---\n\n# Modernizing an Unbounce page (responsive rewrite)\n\nTurn a page built in the Unbounce builder into clean, responsive flexbox/grid\nHTML — **pixel-faithful to the original on desktop, reflowing sensibly on\nmobile**. This is a REPLICATION task with zero creative latitude: same copy,\nsame images, same fonts, same colors, same element counts. The only thing that\nchanges is the layout model (absolute positioning → flex/grid).\n\nThe pipeline is two deliberate stages:\n\n1. **Import** — `create_variant_from_existing_variant` clones the builder-built\n   source into an MCP-managed variant that renders identically (deterministic;\n   every string, image URL, font, and form field lands in the copy verbatim).\n2. **Rewrite** (this skill) — read that copy, restructure its layout to\n   responsive flex/grid, and write it back **in place** with\n   `update_variant_from_html`.\n\nExtraction fidelity is stage 1's job and it is deterministic — never work from\nthe original builder page directly, and never re-derive content from screenshots\nor memory. Your job is only the layout transformation.\n\n## Language with the user\n\nNever say \"modernize\", \"modernization\", \"replica\", or platform-internal terms\nto the user. Their page is fine; say \"make your page responsive\" and \"an\neditable copy of your page\". The result cannot be edited in the Unbounce\nbuilder — all future edits go through MCP tools; say so at handover, and never\nsuggest the builder.\n\n## Workflow\n\n**Step 1 — Resolve the target.** Identify the page (`list_client_pages`) and\nvariant (`list_page_variants`). If the target variant is builder-built (not\nMCP-managed), tell the user in one line what is about to happen — e.g. _\"I'll\ncreate an editable copy of your page, then make that copy responsive — your\noriginal stays untouched\"_ — then run `create_variant_from_existing_variant`\n(no `target_page` ⇒ new page). No further permission ceremony is needed; the\ncopy is additive and safe. Relay any conversion warnings honestly. A\nfixed-width \"autoscale\" source converts fine — the conversion report notes that\nruntime viewport scaling isn't preserved; that is expected and harmless here,\nbecause you rewrite the page responsive from scratch (Step 4), discarding the\nscaling entirely. If the target is already an MCP-managed imported copy, skip\nstraight to Step 2.\n\n**Step 2 — Read the copy.** `get_variant` on the imported variant. Download the\n`html_ref` / `css_refs` sources and any `scripts` entry's `ref` (via `download`, or\n`download_inband` if you cannot run shell commands). This body is the **sole\nsource of truth** for every value: copy strings, image URLs (with their\n`srcset`), `@font-face` blocks, colors, dimensions, form fields, `<ub:dynamic>`\ntags. Never guess a value, never take one from a screenshot, never reconstruct\nfrom memory. If the copy came from an autoscale source, its CSS wraps lengths in\n`calc(<px> * var(--scale, 1))` and it may carry a viewport scale script —\nignore both: read the plain px value (the `* var(--scale)` is the fixed-width\nscaling you are removing) and never copy the scale script into the rewrite. Your\nresponsive layout comes from the Step 3 rows, not these fixed dimensions.\n\n**Step 3 — Get the layout skeleton and fidelity signals.** `get_layout_hints`\non the same variant. It returns, per section: `rows` (element ids clustered\ninto visual rows, left-to-right), per-element geometry,\n`cross_section_overlays` (elements whose vertical span crosses into later\nsections), and `design_width` (the fixed canvas width). **The rows are your\nflex/grid structure.** Do not derive structure from the absolute coordinates\nyourself, and never translate `top`/`left` values through into the rewrite.\nIt also returns measured fidelity signals — `page_defaults` (the page's real\nbase text color and typography), per-section backgrounds, per-element\ncolors/typography/text/image/link inventories, `palette`, `loaded_fonts`,\n`row_stats`, `content_extent`, `hidden_elements`. Those are ground truth:\nauthor from them per [rules/color.md](rules/color.md), never from assumption.\nIf hints come back empty for a variant that plainly has a positioned tree,\nstop and report it (see [rules/verification.md](rules/verification.md)).\n\n**Step 4 — Audit, in writing, before any HTML.** Post a compact audit into the\nconversation (it must survive context compaction): per section — the row\nstructure from hints, the element **counts** per row, every text string\n(verbatim), every image URL + srcset, fonts, colors, form fields\n(name/type/order/options/submit label), interaction states (`:hover`/`:focus`),\nand every cross-section overlay with its pattern (column vs centered). Every\nvalue in your output must trace back to an audit row.\n\n**Step 5 — Write the responsive HTML.** Follow\n[rules/layout.md](rules/layout.md) (section/inner max-width pattern, flex/grid\nfrom hint rows, overlay handling) and\n[rules/replication.md](rules/replication.md) (verbatim preservation). If the\nuser also asked for a change (\"modernize it and swap the headline\"), use\ntwo-pass authoring: pass 1 is a content-identical rewrite, verified; only then\napply their change (see TWO-PASS in rules/replication.md).\n\n**Step 6 — Self-check before writing back.** Run the checklist in\n[rules/verification.md](rules/verification.md) — text walk, count checks, the\nclosure checks against the extracted signals (image-src, link-href, palette,\nfont sets; the WCAG contrast table from [rules/color.md](rules/color.md)), and\nthe hard stops (`position:absolute` budget, zero authored `cbc-*` references,\nflex/grid present, per-section max-width, overlay columns reserved). Fix\nfailures before delivering; never rationalize past a hard stop.\n\n**Step 6b — Carry GA click tracking across.** A Classic page's link clicks are\ntracked by Unbounce's built-in GA link tracker, which keys off builder elements.\nYour rewrite is hand-written `<a>` tags, so that tracker stops attaching and the\ncustomer silently loses click data they had before. Preserving it is replication\nfidelity, not a redesign — so include\n[`../mcp-page-authoring/scripts/ga-click-tracking.js`](../mcp-page-authoring/scripts/ga-click-tracking.js)\nas a `scripts` entry (name it e.g. \"GA click tracking\", placement `body_bottom`).\nNever fork or hand-roll it. It feature-detects `gtag`/`ga` and no-ops on domains\nwithout the integration, so it is safe to add unconditionally.\n\n**Send it as a `ref`, not a `tag`.** Read the file, `upload` it, and pass the\n`upload://` reference it returns as the entry's `ref` — see\n[Writing a `scripts` entry](../mcp-page-authoring/SKILL.md#writing-a-scripts-entry).\n\"Pass its contents verbatim\" is not a shape `update_variant_from_html` accepts:\nan entry is a bare `upload://` string, or an object with exactly one of `ref`,\n`src` or `tag`. Handing it the raw JavaScript as a string fails loudly, which is\nfine.\n\nA `tag` is accepted, and what happens next depends on the tag. A bare\n`<script>…</script>` is unwrapped on write and stored exactly as a `ref` would\nbe, so it does round-trip. An **attributed** one — `<script type=\"text/javascript\">`\n— is stored verbatim, opening tag and all, and comes back as a `tag` whose text\nstarts with `<script`. Use `ref` so there is a single shape either skill can\nrecognise, and so the entry you re-send later is the one you read.\n\n**Pass back every `scripts` entry the variant already had, plus this one.** Step 7\nhas you send a complete `scripts` set, and in that call anything you leave out is\ndeleted — so \"don't add a second copy\" must not become \"don't include it\". You\nalready downloaded the existing entries in Step 2; re-send each one unchanged. If\nyou are making no script change at all, omit `scripts` entirely instead, which\npreserves what is there.\n\n**Recognising an entry that already carries this tracking:** its body **contains**\nthe line `// Google Analytics click tracking.` — the script is passed verbatim, so\nthat string is present in any entry either skill created. Test for the line being\npresent, not for the body starting with it: `get_variant` hands a JS-body script\nback as a `ref` you must download, and the `scripts_preserved` / `removed_scripts`\nreports give a `tag` that starts with `<script>`. Step 2 has already downloaded\nevery script here, so the bodies are to hand. If one is there, re-send it as-is\nand add nothing; a second copy double-counts every click, which is worse than the\nunder-count it was meant to fix and much harder to notice.\n\nThe why and the guardrails (never add the GA loader) live in\n[`../mcp-page-authoring/rules/google-analytics.md`](../mcp-page-authoring/rules/google-analytics.md).\n\n**Step 7 — Write back in place and hand over.** `update_variant_from_html` on\nthe same variant. It is a TRUE FULL REPLACE: pass the complete artifact set\n(html + all css + all js) every time — anything omitted is dropped. `scripts` is\nthe one exception to \"every time\", and only because omitting the array entirely\nis how you say \"change no scripts\"; see the paragraph below before you pass it.\n\n**`scripts` deserves its own care.** Passing the array replaces the complete set,\nand a variant can carry entries nobody authored through these tools — an Unbounce\npopup attaches itself as one. Dropping such an entry deletes a customer's popup or\ntracking pixel, and nothing about the rendered page shows it happened. So re-send\nevery entry you read in Step 2, or omit `scripts` altogether if you are changing\nnone of them (omission preserves them). This is the one place where \"pass\neverything\" and this skill's promise to _preserve user customizations verbatim_\ncan pull apart if you are not deliberate.\n\nThe change is staged, never published by you. Hand the user: what you did (one line), the\n`preview_ref` from a fresh `get_variant` (plus the builder preview link from\n`list_page_variants` for the original, so they can compare), the evidence\nsummary from the self-check, and any genuine differences — concrete and\nspecific, or \"none\". Publishing, traffic, and goals are the user's call.\n\n## Hard invariants (the load-bearing rules)\n\n- **No creative changes. No additions.** Same typo, same order, same counts.\n  Nothing added that has no source element — no nav, no sticky header, no hover\n  effects the source lacks. Conversion-optimization defaults from\n  `mcp-page-authoring` do NOT apply to a rewrite — replication trumps\n  landing-page best practices. **One deliberate exception:** the GA\n  click-tracking script in Step 6b. It adds no content and changes nothing a\n  visitor sees; it restores instrumentation the source page already had and the\n  rewrite would otherwise drop. Nothing else earns an exception here.\n- **Every source text string appears verbatim** in the rewrite (whitespace-\n  insensitive). Element names, ids, and image filenames are NOT content.\n- **Reuse every asset by its exact URL**, keeping `srcset`/`image-set` and\n  `background-position`/`size`/`repeat` verbatim. Copy `@font-face` blocks and\n  `<ub:dynamic>` tags through unchanged.\n- **Forms:** plain `<form>` in your output; preserve field names, types, order,\n  options, and the submit label exactly (the server re-wires submission on\n  write). Preserve the hidden form-confirmation overlay (`cfm-*` markup) and\n  its trigger script verbatim if the copy has one.\n- **Preserve user customizations verbatim**: custom-HTML embeds, tracking\n  scripts, hand-applied CSS classes. Flag (don't rewrite) any script selectors\n  that target old ids.\n- **No subagent delegation.** The source must stay in the same context as the\n  build — a subagent without the verbatim source invents copy.\n- **Stay in your lane at delivery**: staged in-place update, no publish, no\n  traffic, no goal changes.\n\nLong-form rules, worked examples, and the catalog of real past failures:\n[rules/replication.md](rules/replication.md) ·\n[rules/layout.md](rules/layout.md) ·\n[rules/color.md](rules/color.md) ·\n[rules/verification.md](rules/verification.md) ·\n[rules/failure-catalog.md](rules/failure-catalog.md)\n"
Full snapshot data
{
  "description": "Rewrite an imported (absolutely-positioned) Unbounce Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Classic page, or edit a page that was hand-built in the Unbounce Classic builder — phrasings like \"modernize this page\", \"make my page responsive\", \"convert my old page\", \"clean HTML version\". Replication-faithful — this is a layout rewrite, never a redesign. Not for AI Builder pages, which stay editable as they are (mcp-ai-builder-authoring).",
  "included_files": [
    {
      "relative_path": "rules/color.md",
      "size_in_bytes": 6843
    },
    {
      "relative_path": "rules/failure-catalog.md",
      "size_in_bytes": 5157
    },
    {
      "relative_path": "rules/layout.md",
      "size_in_bytes": 6711
    },
    {
      "relative_path": "rules/replication.md",
      "size_in_bytes": 6429
    },
    {
      "relative_path": "rules/verification.md",
      "size_in_bytes": 5833
    }
  ],
  "name": "mcp-modernize",
  "skill_md_contents": "---\nname: mcp-modernize\ndescription: Rewrite an imported (absolutely-positioned) Unbounce Classic page variant as clean responsive HTML through Unbounce MCP. Use when the user asks to modernize a page, make a page responsive, get rid of absolute positioning, make a clean-HTML version of an existing Classic page, or edit a page that was hand-built in the Unbounce Classic builder — phrasings like \"modernize this page\", \"make my page responsive\", \"convert my old page\", \"clean HTML version\". Replication-faithful — this is a layout rewrite, never a redesign. Not for AI Builder pages, which stay editable as they are (mcp-ai-builder-authoring).\nrequires:\n  mcpServers:\n    - unbounce-mcp\n---\n\n# Modernizing an Unbounce page (responsive rewrite)\n\nTurn a page built in the Unbounce builder into clean, responsive flexbox/grid\nHTML — **pixel-faithful to the original on desktop, reflowing sensibly on\nmobile**. This is a REPLICATION task with zero creative latitude: same copy,\nsame images, same fonts, same colors, same element counts. The only thing that\nchanges is the layout model (absolute positioning → flex/grid).\n\nThe pipeline is two deliberate stages:\n\n1. **Import** — `create_variant_from_existing_variant` clones the builder-built\n   source into an MCP-managed variant that renders identically (deterministic;\n   every string, image URL, font, and form field lands in the copy verbatim).\n2. **Rewrite** (this skill) — read that copy, restructure its layout to\n   responsive flex/grid, and write it back **in place** with\n   `update_variant_from_html`.\n\nExtraction fidelity is stage 1's job and it is deterministic — never work from\nthe original builder page directly, and never re-derive content from screenshots\nor memory. Your job is only the layout transformation.\n\n## Language with the user\n\nNever say \"modernize\", \"modernization\", \"replica\", or platform-internal terms\nto the user. Their page is fine; say \"make your page responsive\" and \"an\neditable copy of your page\". The result cannot be edited in the Unbounce\nbuilder — all future edits go through MCP tools; say so at handover, and never\nsuggest the builder.\n\n## Workflow\n\n**Step 1 — Resolve the target.** Identify the page (`list_client_pages`) and\nvariant (`list_page_variants`). If the target variant is builder-built (not\nMCP-managed), tell the user in one line what is about to happen — e.g. _\"I'll\ncreate an editable copy of your page, then make that copy responsive — your\noriginal stays untouched\"_ — then run `create_variant_from_existing_variant`\n(no `target_page` ⇒ new page). No further permission ceremony is needed; the\ncopy is additive and safe. Relay any conversion warnings honestly. A\nfixed-width \"autoscale\" source converts fine — the conversion report notes that\nruntime viewport scaling isn't preserved; that is expected and harmless here,\nbecause you rewrite the page responsive from scratch (Step 4), discarding the\nscaling entirely. If the target is already an MCP-managed imported copy, skip\nstraight to Step 2.\n\n**Step 2 — Read the copy.** `get_variant` on the imported variant. Download the\n`html_ref` / `css_refs` sources and any `scripts` entry's `ref` (via `download`, or\n`download_inband` if you cannot run shell commands). This body is the **sole\nsource of truth** for every value: copy strings, image URLs (with their\n`srcset`), `@font-face` blocks, colors, dimensions, form fields, `<ub:dynamic>`\ntags. Never guess a value, never take one from a screenshot, never reconstruct\nfrom memory. If the copy came from an autoscale source, its CSS wraps lengths in\n`calc(<px> * var(--scale, 1))` and it may carry a viewport scale script —\nignore both: read the plain px value (the `* var(--scale)` is the fixed-width\nscaling you are removing) and never copy the scale script into the rewrite. Your\nresponsive layout comes from the Step 3 rows, not these fixed dimensions.\n\n**Step 3 — Get the layout skeleton and fidelity signals.** `get_layout_hints`\non the same variant. It returns, per section: `rows` (element ids clustered\ninto visual rows, left-to-right), per-element geometry,\n`cross_section_overlays` (elements whose vertical span crosses into later\nsections), and `design_width` (the fixed canvas width). **The rows are your\nflex/grid structure.** Do not derive structure from the absolute coordinates\nyourself, and never translate `top`/`left` values through into the rewrite.\nIt also returns measured fidelity signals — `page_defaults` (the page's real\nbase text color and typography), per-section backgrounds, per-element\ncolors/typography/text/image/link inventories, `palette`, `loaded_fonts`,\n`row_stats`, `content_extent`, `hidden_elements`. Those are ground truth:\nauthor from them per [rules/color.md](rules/color.md), never from assumption.\nIf hints come back empty for a variant that plainly has a positioned tree,\nstop and report it (see [rules/verification.md](rules/verification.md)).\n\n**Step 4 — Audit, in writing, before any HTML.** Post a compact audit into the\nconversation (it must survive context compaction): per section — the row\nstructure from hints, the element **counts** per row, every text string\n(verbatim), every image URL + srcset, fonts, colors, form fields\n(name/type/order/options/submit label), interaction states (`:hover`/`:focus`),\nand every cross-section overlay with its pattern (column vs centered). Every\nvalue in your output must trace back to an audit row.\n\n**Step 5 — Write the responsive HTML.** Follow\n[rules/layout.md](rules/layout.md) (section/inner max-width pattern, flex/grid\nfrom hint rows, overlay handling) and\n[rules/replication.md](rules/replication.md) (verbatim preservation). If the\nuser also asked for a change (\"modernize it and swap the headline\"), use\ntwo-pass authoring: pass 1 is a content-identical rewrite, verified; only then\napply their change (see TWO-PASS in rules/replication.md).\n\n**Step 6 — Self-check before writing back.** Run the checklist in\n[rules/verification.md](rules/verification.md) — text walk, count checks, the\nclosure checks against the extracted signals (image-src, link-href, palette,\nfont sets; the WCAG contrast table from [rules/color.md](rules/color.md)), and\nthe hard stops (`position:absolute` budget, zero authored `cbc-*` references,\nflex/grid present, per-section max-width, overlay columns reserved). Fix\nfailures before delivering; never rationalize past a hard stop.\n\n**Step 6b — Carry GA click tracking across.** A Classic page's link clicks are\ntracked by Unbounce's built-in GA link tracker, which keys off builder elements.\nYour rewrite is hand-written `<a>` tags, so that tracker stops attaching and the\ncustomer silently loses click data they had before. Preserving it is replication\nfidelity, not a redesign — so include\n[`../mcp-page-authoring/scripts/ga-click-tracking.js`](../mcp-page-authoring/scripts/ga-click-tracking.js)\nas a `scripts` entry (name it e.g. \"GA click tracking\", placement `body_bottom`).\nNever fork or hand-roll it. It feature-detects `gtag`/`ga` and no-ops on domains\nwithout the integration, so it is safe to add unconditionally.\n\n**Send it as a `ref`, not a `tag`.** Read the file, `upload` it, and pass the\n`upload://` reference it returns as the entry's `ref` — see\n[Writing a `scripts` entry](../mcp-page-authoring/SKILL.md#writing-a-scripts-entry).\n\"Pass its contents verbatim\" is not a shape `update_variant_from_html` accepts:\nan entry is a bare `upload://` string, or an object with exactly one of `ref`,\n`src` or `tag`. Handing it the raw JavaScript as a string fails loudly, which is\nfine.\n\nA `tag` is accepted, and what happens next depends on the tag. A bare\n`<script>…</script>` is unwrapped on write and stored exactly as a `ref` would\nbe, so it does round-trip. An **attributed** one — `<script type=\"text/javascript\">`\n— is stored verbatim, opening tag and all, and comes back as a `tag` whose text\nstarts with `<script`. Use `ref` so there is a single shape either skill can\nrecognise, and so the entry you re-send later is the one you read.\n\n**Pass back every `scripts` entry the variant already had, plus this one.** Step 7\nhas you send a complete `scripts` set, and in that call anything you leave out is\ndeleted — so \"don't add a second copy\" must not become \"don't include it\". You\nalready downloaded the existing entries in Step 2; re-send each one unchanged. If\nyou are making no script change at all, omit `scripts` entirely instead, which\npreserves what is there.\n\n**Recognising an entry that already carries this tracking:** its body **contains**\nthe line `// Google Analytics click tracking.` — the script is passed verbatim, so\nthat string is present in any entry either skill created. Test for the line being\npresent, not for the body starting with it: `get_variant` hands a JS-body script\nback as a `ref` you must download, and the `scripts_preserved` / `removed_scripts`\nreports give a `tag` that starts with `<script>`. Step 2 has already downloaded\nevery script here, so the bodies are to hand. If one is there, re-send it as-is\nand add nothing; a second copy double-counts every click, which is worse than the\nunder-count it was meant to fix and much harder to notice.\n\nThe why and the guardrails (never add the GA loader) live in\n[`../mcp-page-authoring/rules/google-analytics.md`](../mcp-page-authoring/rules/google-analytics.md).\n\n**Step 7 — Write back in place and hand over.** `update_variant_from_html` on\nthe same variant. It is a TRUE FULL REPLACE: pass the complete artifact set\n(html + all css + all js) every time — anything omitted is dropped. `scripts` is\nthe one exception to \"every time\", and only because omitting the array entirely\nis how you say \"change no scripts\"; see the paragraph below before you pass it.\n\n**`scripts` deserves its own care.** Passing the array replaces the complete set,\nand a variant can carry entries nobody authored through these tools — an Unbounce\npopup attaches itself as one. Dropping such an entry deletes a customer's popup or\ntracking pixel, and nothing about the rendered page shows it happened. So re-send\nevery entry you read in Step 2, or omit `scripts` altogether if you are changing\nnone of them (omission preserves them). This is the one place where \"pass\neverything\" and this skill's promise to _preserve user customizations verbatim_\ncan pull apart if you are not deliberate.\n\nThe change is staged, never published by you. Hand the user: what you did (one line), the\n`preview_ref` from a fresh `get_variant` (plus the builder preview link from\n`list_page_variants` for the original, so they can compare), the evidence\nsummary from the self-check, and any genuine differences — concrete and\nspecific, or \"none\". Publishing, traffic, and goals are the user's call.\n\n## Hard invariants (the load-bearing rules)\n\n- **No creative changes. No additions.** Same typo, same order, same counts.\n  Nothing added that has no source element — no nav, no sticky header, no hover\n  effects the source lacks. Conversion-optimization defaults from\n  `mcp-page-authoring` do NOT apply to a rewrite — replication trumps\n  landing-page best practices. **One deliberate exception:** the GA\n  click-tracking script in Step 6b. It adds no content and changes nothing a\n  visitor sees; it restores instrumentation the source page already had and the\n  rewrite would otherwise drop. Nothing else earns an exception here.\n- **Every source text string appears verbatim** in the rewrite (whitespace-\n  insensitive). Element names, ids, and image filenames are NOT content.\n- **Reuse every asset by its exact URL**, keeping `srcset`/`image-set` and\n  `background-position`/`size`/`repeat` verbatim. Copy `@font-face` blocks and\n  `<ub:dynamic>` tags through unchanged.\n- **Forms:** plain `<form>` in your output; preserve field names, types, order,\n  options, and the submit label exactly (the server re-wires submission on\n  write). Preserve the hidden form-confirmation overlay (`cfm-*` markup) and\n  its trigger script verbatim if the copy has one.\n- **Preserve user customizations verbatim**: custom-HTML embeds, tracking\n  scripts, hand-applied CSS classes. Flag (don't rewrite) any script selectors\n  that target old ids.\n- **No subagent delegation.** The source must stay in the same context as the\n  build — a subagent without the verbatim source invents copy.\n- **Stay in your lane at delivery**: staged in-place update, no publish, no\n  traffic, no goal changes.\n\nLong-form rules, worked examples, and the catalog of real past failures:\n[rules/replication.md](rules/replication.md) ·\n[rules/layout.md](rules/layout.md) ·\n[rules/color.md](rules/color.md) ·\n[rules/verification.md](rules/verification.md) ·\n[rules/failure-catalog.md](rules/failure-catalog.md)\n"
}

SHA-256 of public snapshot: 0dce91ec62a8ad820886c8cab21e1af0c2d652da12c7a9de22e347599dd91973