Skip to content
cccskills
FreePublished on GitHub

stitch-html-components

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.

The English summary is being prepared. Showing the original description.

See how to install

Files included (3)

  • SKILL.md12.4 KB
  • resources/architecture-checklist.md3.6 KB
  • scripts/fetch-stitch.sh1.3 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

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 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:

mkdir -p temp && cp "path/to/design.html" temp/source.html

From a URL:

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 <head> (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/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 <html> */
[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/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 <div> where a semantic element fits:

Stitch element→ HTML element
Page shell / app chrome<body> → <header> + <main> + <footer>
Navigation bar<nav aria-label="Main navigation">
Primary content area<main id="main-content">
Article/post/card content<article>
Sidebar<aside>
Section of page<section aria-labelledby="section-id">
Button (no href)<button type="button">
Link with navigation<a href="...">
Form container<form> with <label> for every input
Images<img alt="descriptive text">

Mobile HTML template:

<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <!-- Critical for mobile: prevent zoom, respect viewport -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
  <!-- iOS PWA meta tags -->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="default">
  <!-- Theme color (top browser bar on Android) -->
  <meta name="theme-color" content="[--color-background hex]">

  <title>[Screen title]</title>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="stylesheet" href="css/tokens.css">
  <link rel="stylesheet" href="css/base.css">
  <link rel="stylesheet" href="css/components.css">
</head>
<body>
  <!-- Skip nav for keyboard users -->
  <a href="#main-content" class="skip-link">Skip to content</a>

  <!-- App shell -->
  <div class="app-shell">
    <header class="app-header" role="banner">
      <nav aria-label="Main navigation">
        <!-- Nav content -->
      </nav>
    </header>

    <main id="main-content" class="app-main">
      <!-- Page content -->
    </main>

    <!-- Bottom nav (mobile) -->
    <nav class="bottom-nav" aria-label="Tab navigation">
      <!-- Tab items -->
    </nav>
  </div>

  <script src="js/main.js" type="module"></script>
</body>
</html>

Step 6: Mobile-first CSS rules

Every component must follow these mobile constraints:

Touch targets

/* All interactive elements: minimum 44×44px tap area */
button, a, [role="button"] {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

Scrolling

/* Smooth scroll on iOS */
.scrollable {
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain; /* Prevent scroll chaining */
}

Bottom navigation bar

.bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  /* Account for iOS home indicator */
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  display: flex;
  justify-content: space-around;
  z-index: 100;
}

/* Push main content above bottom nav */
.app-main {
  padding-bottom: calc(60px + env(safe-area-inset-bottom));
}

Responsive breakpoints

/* Mobile-first: base styles are for mobile */

/* Tablet (768px+) */
@media (min-width: 768px) {
  .container { max-width: 720px; margin: 0 auto; }
}

/* Desktop (1024px+) */
@media (min-width: 1024px) {
  .container { max-width: 1200px; }
  .bottom-nav { display: none; } /* Hide bottom nav, use sidebar */
  .sidebar { display: block; }   /* Show desktop sidebar */
}

Step 7: Minimal JavaScript

Keep JS to an absolute minimum. The only things that need JS:

  1. Theme toggle (dark/light)
  2. Mobile menu open/close
  3. Accordion/tabs interactive behavior
// js/main.js

// Dark mode toggle
const html = document.documentElement;
const savedTheme = localStorage.getItem('theme') || 'light';
html.setAttribute('data-theme', savedTheme);

document.getElementById('theme-toggle')?.addEventListener('click', () => {
  const next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
  html.setAttribute('data-theme', next);
  localStorage.setItem('theme', next);
});

// Mobile menu toggle
document.getElementById('menu-toggle')?.addEventListener('click', () => {
  const nav = document.getElementById('mobile-nav');
  const expanded = nav.getAttribute('aria-expanded') === 'true';
  nav.setAttribute('aria-expanded', String(!expanded));
  nav.classList.toggle('is-open');
});

Step 8: Capacitor / WebView notes

If this HTML will be embedded in a Capacitor or Ionic app:

  • All asset paths must be relative (no / prefix): ./css/tokens.css, ./assets/logo.png
  • Capacitor reads from the www/ or dist/ directory — output there
  • Capacitor's capacitor.config.json sets the WebDir: "webDir": "www"
  • To call native APIs (camera, filesystem), use the Capacitor plugin JS APIs — beyond this skill's scope

Troubleshooting

IssueFix
Fonts look zoomed on iOS rotationAdd -webkit-text-size-adjust: 100% to html
Content under notchAdd env(safe-area-inset-*) padding
Scrolling feels laggy on iOSAdd -webkit-overflow-scrolling: touch
Bottom nav overlaps contentAdd padding-bottom to <main> equal to nav height + safe area
Click delay on mobile (300ms)Add touch-action: manipulation to buttons

Integration

  • Run stitch-design-system first to generate design-tokens.css — import it instead of recreating tokens
  • Run stitch-a11y after for an accessibility pass
  • Run stitch-animate to add CSS-only transitions (zero JS needed for most animations)

References

  • resources/mobile-template.html — Full mobile HTML boilerplate
  • resources/architecture-checklist.md — Pre-ship checklist
  • scripts/fetch-stitch.sh — Reliable GCS HTML downloader

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Audits Stitch-generated components for WCAG 2.1 AA accessibility issues and applies fixes — semantic HTML, ARIA attributes, keyboard navigation, focus management, and screen reader support.

The English summary is being prepared. Showing the original description.

gabelul/stitch-kit45Updated Jul 21, 2026

Adds a purposeful animation layer to Stitch-generated components — CSS transitions, Framer Motion (React/Next.js), or Svelte transitions. Always respects prefers-reduced-motion.

The English summary is being prepared. Showing the original description.

gabelul/stitch-kit45Updated Jul 21, 2026

Analyzes a Stitch project's screens and synthesizes a natural-language DESIGN.md — visual atmosphere, color palette with hex values, typography rules, and Stitch-ready prompt snippets. Use this before stitch-loop or any multi-page build to establish design consistency.

The English summary is being prepared. Showing the original description.

gabelul/stitch-kit45Updated Jul 21, 2026

Extracts a Stitch design and generates production code artifacts — CSS custom properties with dark mode tokens, a Tailwind v4 @theme block, and a semantic design system document. Run this before framework conversion skills.

The English summary is being prepared. Showing the original description.

gabelul/stitch-kit45Updated Jul 21, 2026

Conversational design ideation agent that researches trends, explores visual directions, and refines ideas through adaptive questioning — then produces a rich PRD document and auto-generates Stitch screens. Your design buddy that thinks deeply before designing.

The English summary is being prepared. Showing the original description.

gabelul/stitch-kit45Updated Jul 21, 2026

Iteratively build multi-page websites using Stitch. Reads next-prompt.md (the baton), generates the next page with Stitch MCP, integrates it into the site, then updates next-prompt.md to continue the loop. Works with stitch-design-md and stitch-ui-prompt-architect for consistent multi-page output.

The English summary is being prepared. Showing the original description.

gabelul/stitch-kit45Updated Jul 21, 2026

See all skills by gabelul

Report a problem with this skill