--- name: stitch-html-components description: Converts a Stitch screen, a local HTML file, or a URL into clean, platform-agnostic HTML5 + CSS — semantic markup, CSS custom properties for theming, dark mode via prefers-color-scheme, mobile-first responsive, zero framework dependencies. Works in browsers, WebViews, Capacitor, and Ionic. Only the Stitch route needs an API key. allowed-tools: - "stitch*:*" - "Bash" - "Read" - "Write" --- # Stitch → HTML5 + CSS (Platform-Agnostic) You are a frontend engineer specializing in clean, dependency-free HTML and CSS. You convert HTML sources — Stitch screens, local files, or URLs — into semantic HTML5 with CSS custom properties — no React, no Svelte, no build step. The output runs anywhere: desktop browsers, mobile browsers, iOS WebView, Android WebView, Capacitor apps, and Ionic shells. ## When to use this skill Use this skill when: - The user wants **platform-agnostic** output — "just HTML", "no framework", "works everywhere" - The target is a **WebView** in a mobile app (Capacitor, Ionic, Cordova) - Building a **static site** or embedding in a CMS - The user hasn't chosen a framework yet and wants a working prototype - Generating the **HTML base** before wrapping with Capacitor for native mobile ## Prerequisites An HTML source. Any one of these works: - A **Stitch screen** — needs Stitch MCP access and a generated screen - A **local HTML file** — no Stitch account required - A **URL** — no Stitch account required ## Step 1: Resolve the source Everything downstream reads one file: `temp/source.html`. Get the HTML there by whichever route matches what the user gave you, then continue at Step 2 — the rest of this skill is identical regardless of where the markup came from. **From a Stitch screen:** 1. **Namespace discovery** — `list_tools` to find the Stitch MCP prefix 2. **Fetch metadata** — `[prefix]:get_screen` for the design JSON 3. **Download HTML** — GCS URLs need the reliable downloader: ```bash bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" ``` 4. **Visual audit** — check `screenshot.downloadUrl` before rewriting. Append `=s0` to that URL for full resolution; the bare URL serves a 512px thumbnail regardless of the `width`/`height` the API reports. **From a local HTML file:** ```bash mkdir -p temp && cp "path/to/design.html" temp/source.html ``` **From a URL:** ```bash bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html" ``` Despite the name, that script is a generic hardened downloader — follows redirects, retries transient failures, handles gzip, and fails loudly on an empty result. It does not care whether the URL points at Stitch. **From a screenshot:** there's no upload route — the Stitch MCP API has no image-upload tool. Either recreate the design from a text prompt via `stitch-mcp-generate-screen-from-text`, or hand-write the HTML and use the local-file route above. > Only the Stitch route needs an API key. Converting a local file or a URL works with no Google account at all. ## Step 2: File structure ``` output/ ├── index.html ← Main page (or rename per screen) ├── css/ │ ├── tokens.css ← CSS custom properties (light + dark) │ ├── base.css ← Reset, body defaults, typography │ └── components.css ← Component styles ├── js/ │ └── main.js ← Minimal JS (theme toggle, mobile menu only) └── assets/ └── images/ ``` For multi-screen projects, each screen gets its own HTML file. Shared CSS lives in `tokens.css` and `base.css`. ## Step 3: CSS custom properties Map source colors to semantic tokens. Always generate **both light and dark** at the same time. Resolve the hex values in this order: 1. **Inline `tailwind.config`** in `
` (what Stitch emits) — use it directly if present. 2. **CSS custom properties** already in the source (`:root { --color-primary: ... }`) — common in hand-written and templated HTML. 3. **A linked or inline stylesheet** — parse declared colors, font-families, radii, spacing. 4. **Last resort** — derive tokens from the most frequent computed values in the markup (dominant background, text color, accent, heading/body font, border radius), and tell the user what you inferred so they can correct it. The URL route only downloads the single HTML response — externally-linked stylesheets may not come along for the ride. If none of the above resolves a token, say so instead of inventing a palette. ```css /* css/tokens.css */ :root { --color-background: [hex]; --color-surface: [hex]; --color-primary: [hex]; --color-primary-fg: [hex]; --color-text: [hex]; --color-text-muted: [hex]; --color-border: [hex]; --font-sans: [font-stack]; --font-mono: ui-monospace, monospace; --radius-sm: [value]; --radius-md: [value]; --radius-lg: [value]; --shadow-sm: 0 1px 3px rgb(0 0 0 / 0.1); --shadow-md: 0 4px 12px rgb(0 0 0 / 0.1); --transition: 150ms cubic-bezier(0.4, 0, 0.2, 1); } /* Dark mode — system preference */ @media (prefers-color-scheme: dark) { :root { --color-background: [dark-hex]; --color-surface: [dark-hex]; --color-primary: [dark-adjusted-hex]; --color-primary-fg: [dark-hex]; --color-text: [dark-hex]; --color-text-muted: [dark-hex]; --color-border: [dark-hex]; } } /* Dark mode — manual toggle via data-theme="dark" on */ [data-theme="dark"] { --color-background: [dark-hex]; --color-surface: [dark-hex]; /* ... same values as above */ } ``` If the project already has a `design-tokens.css` (from `stitch-design-system`), import it instead of recreating tokens. ## Step 4: Base CSS ```css /* css/base.css */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { font-size: 16px; /* Safe area insets for notched phones */ padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); -webkit-text-size-adjust: 100%; /* Prevent font scaling on iOS rotation */ } body { font-family: var(--font-sans); background-color: var(--color-background); color: var(--color-text); line-height: 1.5; -webkit-font-smoothing: antialiased; } /* Skip link for accessibility */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border-width: 0; } .skip-link { /* ... see stitch-a11y skill */ } /* Focus ring — keyboard only */ *:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: 2px; } /* Reduced motion */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } ``` ## Step 5: Semantic HTML structure Convert Stitch layout to semantic HTML5. Never use `