Communitygithub.com

jovd83/prototype-sketching-skill

Reversible, non-destructive hand-sketched skin (Balsamiq, Sharpie, Pencil, Doodle, Blueprint) for Angular/React/Vue/static web apps, with an adjustable 0-100% sketchiness level and an interactive overlay. Look-and-feel only.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add jovd83/prototype-sketching-skill

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

문서

Prototype Sketching Skill

Make a working web app look hand-drawn so clients see it is a prototype, not a finished product. This is a look-and-feel skin only. It is purely additive and fully reversible.

Scope guardrails (read first, never violate)

  1. Only touch styling entry points and index.html. Append a stylesheet, paste one SVG block, set two attributes. Nothing else.
  2. Never edit components, templates, .ts/.tsx/.jsx/.vue logic, routing, state, services, or tests.
  3. Never swap components for sketchy component libraries (e.g. wired-elements) — that rewrites markup. Forbidden.
  4. Never recolor or distort logos, photos, charts, or icons that must stay crisp — use the opt-out class.
  5. Reverting must stay trivial: removing the two <html> attributes turns the whole skin off.

How it works (one mental model)

  • One stylesheet assets/sketch-skin.css defines all 5 styles + the sketchiness ramp.
  • One SVG block assets/sketch-filters.html defines the wobble filters (#sketch-25#sketch-100).
  • Activation is two attributes on <html>: data-sketch="<style>" and data-sketch-level="<0|25|50|75|100>".
  • The look comes from: handwritten font swap + hand-drawn boxes (irregular border-radius, flat fills) + an SVG displacement filter whose strength is the sketchiness level. The font carries text; the filter wobbles box decoration only (never blurs text).

Quick start (do these in order)

  1. Confirm the request is skin-only. If the user wants behavior/layout changes, stop — that is out of scope.
  2. Detect the framework and find its global stylesheet + index.html (see recipe table below).
  3. Pick a style (table in "Styles") and a level (0, 25, 50, 75, or 100).
  4. Add the skin CSS to the project's global styles:
    • Copy assets/sketch-skin.css into the project (e.g. src/styles.scss) or @import it. The font @import is already inside that file (online use).
  5. Paste the SVG filters from assets/sketch-filters.html immediately after the opening <body> tag in index.html. (Required — filter: url(#sketch-…) resolves only if these defs are in the DOM.)
  6. Activate by editing the <html> tag in index.html:
    <html lang="en" data-sketch="balsamiq" data-sketch-level="50">
    
  7. Verify in the browser. To revert, delete the two data-sketch* attributes (the appended CSS/SVG can stay dormant — they do nothing without the attributes).

Styles

data-sketchLookFontUse for
balsamiqClean greyscale wireframe, flat boxesBalsamiq SansThe default "this is a mockup"
sharpieBold black marker, heavy strokePermanent MarkerWhiteboard / workshop sketch
pencilLight graphite, soft strokesGaeguGentle "pencil on paper" draft
doodlePlayful, light color accentsShort StackFriendly, informal concepts
blueprintWhite ink on blue paperPatrick HandTechnical "drawing board" feel

Sketchiness level

data-sketch-level controls how shaky the lines are. It selects a different SVG displacement filter:

LevelEffect
0Hand-drawn boxes + font, but straight, steady lines (cleanest)
25Subtle wobble
50Clearly hand-drawn (recommended default)
75Loose, energetic sketch
100Very rough, maximum "scribble"

If data-sketch is set but data-sketch-level is omitted, the skin defaults to level 50.

Diagonal watermark (optional)

To stamp the whole screen as a draft, add a third <html> attribute with the text to show:

<html data-sketch="balsamiq" data-sketch-level="50" data-sketch-watermark="DRAFT">

data-sketch-watermark paints one faint, hand-lettered word diagonally across the viewport. It is a fixed, non-interactive layer (pointer-events: none), so it never blocks clicks, never changes layout, and stays in place across page and route changes. Any text works (DRAFT, PROTOTYPE, CONFIDENTIAL, a client name…). Remove the attribute to turn it off. With the overlay, a Watermark text field sets it live.

Modals, popups & SPA navigation

Because the skin is activated by attributes on <html> and styled with global [data-sketch] … selectors, anything that appears after activation inherits it automatically — dialogs, popovers, dropdown menus, tooltips and toasts (including portal-mounted ones), and every screen you navigate to in a single-page app. There is nothing to wire per component or per route.

Two things keep it consistent:

  • The selector lists already cover dialog, [popover], [role="dialog"], [aria-modal="true"], .modal, .popover, menus, tooltips and toasts, plus the native ::backdrop.
  • The overlay script watches <body> and re-injects the SVG filters if a framework replaces the body on a route change, so the wobble never silently drops. (With the static-attribute model, paste sketch-filters.html once after <body>; SPA frameworks mount into a child root and leave it intact.)

Framework injection recipes

The skin is framework-agnostic. These are the exact targets; full details in references/implementation.md.

StackAdd CSS toPaste SVG intoSet attributes on
Angularsrc/styles.scss (or styles.css)src/index.html after <body><html> in src/index.html
React / Vitesrc/index.css (imported in main.tsx)index.html after <body><html> in index.html
Vuesrc/assets/main.css (imported in main.ts)index.html after <body><html> in index.html
Static HTMLlink sketch-skin.css in <head>index.html after <body><html> in index.html

Keeping specific assets crisp (opt-out)

The skin will not edit markup, but if the user explicitly asks to protect one element (logo, chart), the only allowed markup change is adding the opt-out hook to that single element:

<img src="logo.svg" class="no-sketch" alt="Logo">

.no-sketch (or data-no-sketch) removes the wobble filter and color overrides from that element. Use sparingly and only when asked.

Interactive preview overlay (optional)

When the user wants to toggle styles live (e.g. show a client a switch), use the overlay instead of static attributes:

  1. Add assets/sketch-skin.css to the global styles (as in Quick start).
  2. Add one script tag before </body>:
    <script src="sketch-toggle.js" defer></script>
    
  3. Done. The script renders a floating panel with OFF + one radio per theme, a 0–100% sketchiness slider, and a watermark text field, flips the <html> attributes live, and remembers the choice in localStorage. It auto-injects the SVG filters (and re-injects them if an SPA replaces the body), so step 5 of Quick start (pasting sketch-filters.html) is not needed.

This is still skin-only and non-destructive — the script just sets attributes. Remove the tag to disable. Choose this model when the request is "let me/the client switch styles"; use static attributes for a fixed, screenshot-stable look.

Screenshot gallery

README.md shows every style and the 0→100% ladder using the PNGs in demo/screenshots/. Those images are pre-rendered; the interactive demo app and the Playwright capture script that generate them live in the project's development source and are not bundled with the installed skill. The skill itself is just assets/ + references/ — no build step, no dependencies.

Examples

Example 1 — Angular demo in Balsamiq, moderate sketch

  • Input: "Make this Angular app look like a Balsamiq wireframe for tomorrow's demo."
  • Actions: append sketch-skin.css to src/styles.scss; paste filters into src/index.html; set <html data-sketch="balsamiq" data-sketch-level="50">.
  • Result: app runs identically; renders as a greyscale wireframe.

Example 2 — React, maximum sharpie

  • Input: "React app, full whiteboard-marker look, really rough."
  • Actions: import sketch-skin.css in main.tsx; paste filters into index.html; set data-sketch="sharpie" data-sketch-level="100".

Example 3 — Turn it off

  • Input: "Switch back to the real UI."
  • Action: delete data-sketch and data-sketch-level from <html>. Done — no other change needed.

Troubleshooting

SymptomCauseFix
Boxes look hand-drawn but lines are perfectly straightSVG filters not in DOM, or level 0Confirm sketch-filters.html is pasted after <body>; set level ≥ 25
Nothing changed at allAttributes missing or CSS not loadedVerify <html data-sketch="…"> is present and sketch-skin.css is in the global styles
Text looks blurryFilter applied to text/whole <body>Do not add filter: to body or text; the skin filters box decoration only — re-copy sketch-skin.css unmodified
Fonts are not handwrittenOffline / blocked Google FontsSelf-host fonts — see assets/fonts/README.md
Page feels sluggish on huge tables/gridsfeDisplacementMap cost on large DOMLower the level, or scope the wobble selector list (see references/implementation.md)
A logo got desaturated/wobblyNo opt-out on that assetAdd class="no-sketch" to that single element
Icon fonts / SVG icons disappearedAggressive flattenAdd no-sketch to the icon container, or see the icon note in references/implementation.md

Reference files (read only when needed)

  • references/styles.md — exact font/palette/stroke spec for each of the 5 styles, and how to add a new style.
  • references/implementation.md — SVG filter math, per-framework step-by-step, selector tuning, offline fonts, performance, revert details.

관련 스킬