Mockup to code skill
Convert static web-design mockup images (AI-generated or hand-made comp/カンプ, single image or a multi-frame section set) into high-fidelity, responsive HTML/CSS. Three modes: pixel-clone, production, hybrid (default for AI comps — regenerate photo/background rasters text-free and UI-free, rebuild type/UI in HTML/CSS, support verified generated lettering decals for non-structural handwritten decoration, reconstruct the visual language). Measurement-driven (manifest, box-diff repair, crop-pair evidence, axis-min review) with a hard LAYOUT LAW: content is built in flow/Grid/Flex inside responsive containers — measured rects are acceptance targets, never absolute coordinates. Includes multi-frame LP fidelity gradients, page composition, FV look-and-tune, and degraded-mode ladders. Trigger when the user wants a design image coded into a web page with high visual fidelity: 「この画像をHTML/CSSにして」「カンプをコーディングして」 「デザイン画像を再現して」 "code this mockup", "implement this design image".From its SKILL.md
npx -y skills add mocchalera/mockup-to-code-skillAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
61.6 KB, ~13.9k tokens by cl100k_base, as published. Nobody here has run it
mockup-to-code
Reverse-engineer a static mockup into HTML/CSS through measurement, not eyeballing — and into a web document, not a screenshot. You interpret meaning and form hypotheses; scripts measure pixels; the browser answers with DOMRects; box diff tells you what to fix; your eyes judge what rendered.
Detailed procedures live in references/ — each phase below names its file.
Read the named reference before running that phase; this file alone is
not enough to execute a phase correctly.
The few things agents skip — and must not. The rest of this file is detail for when you need it; these are the difference between a real run and theater:
- Isolate
WORK_ROOT; normalize every comp before measuring. - Photo-led rasters are regenerated, not faked or dropped: declare
mediaClass: photo, generate to a file before any fallback, never reclassify a subject to svg/UI or ship a contaminated crop (rules 6, 13, 23–25). - Run
asset_preflight.pyafter photo asset decisions and before CSS. A crop that avoids fused text/UI by narrowing the scene still fails when it changes the comp's environment or focal composition (rule 27). - Classify each visible device by owner and anchor before CSS: container content, hero-bound layers, viewport-fixed/global UI, edge typography, generated lettering decal, decoration, or background (rules 7, 16).
- Freeze every display block's source letterform class (gothic/mincho/rounded/
display) before the font bake-off; never buy a bbox pass by distorting text
with CSS transform. For Japanese, mixed-script, vertical, or display-critical
work, invoke the
typographyskill and bind its run ledger/report into the manifest before CSS (rules 22, 28). - When source-signature grain, halftone, scanlines, RGB offset, erosion,
distress, or banded glitch must survive, set
rasterTexture.required:trueexplicitly and invokeraster-texture-reconstruction. Bind itsreadypre-CSS andpasscompletion report; never ship source pixels or rasterize structural copy (rule 55). - Start hybrid multi-frame manifests from
templates/manifest.hybrid-multiframe.min.json, then runcontract_doctor.py --phase pre-cssuntil it passes. This catches malformed geometry, ownership, page-composition, and generated-asset evidence before CSS exists. - Ask the pipeline what is legally next:
mockup_pipeline.py --phase nextreturns one action, detects stale pre-CSS receipts, and caps runs that built below-FV DOM before FV convergence. data-el+ manifest on every important element; box_diff, not your eyes, is the repair signal (rules 2–4, 8, 9).- Flow/Grid/Flex only — measured rects are targets, never coordinates (rule 16).
- FV passes before any below-FV CSS (rule 19); the verdict is computed by
completion_gate.pyand reported verbatim (rules 18, 20). - Run
artifact_check.pybeforecompletion_gate.py: sparse crop pairs, missing bbox ledger, unchecked generated assets, or blended WEB/fidelity scoring meansneeds_workeven when visual-check passes. The artifact report hash-binds the manifest/box/scores it audited; stale or swapped evidence cannot reach complete (rule 26). - A clean
documentElement.scrollWidthis not responsive proof. The widths sweep checks body width, root overflow suppression, meaningful-element visible ratios, and same-document fragments;overflow-x:hidden/clipcannot conceal missing content (rule 31). - Multi-frame comps require executable
pageCompositionsection/seam contracts. Runpage_flow_check.pyafter rendering; a stack of repeated frame-height slabs, undeclared clipping, or unevidenced seams cannot reach complete (rule 30). - When the source explicitly asks for a seamless FV-to-next handoff or scroll
invitation, route
seamless-section-wavesand declare anart-directed-bridge: outgoing environment, opaque destination-owned field, one connective motif, and an incoming next-section preview. A readable wave crop alone is not continuity proof (rule 43). - Inventory fidelity is machine-shaped: every
detailInventoryrow maps to a completion disposition, and a different reviewer judges crop pairs without seeing implementation rationale. The lower score controls (rules 33–34). - Generated card/object rasters declare who owns the frame, background, padding, radius, and bleed. A raster panel inside a CSS card is a double-frame defect.
- Freeze each critical raster's source topology before generation: a section field becomes a copy-space-aware full-field plate; a floating object/diagram/collage becomes a real alpha scene including its shadow. Do not use a framed opaque fallback.
- Large section waves use measured bezier geometry or an off-canvas true-circle arc. A convenient stretched ellipse is blocked without source evidence.
- Critical Japanese headings declare viewport-specific line strings and orphan
fragments; a stranded particle or inflection such as
てis a hard failure.
Hard rules (non-negotiable)
- Do not estimate when you can measure (vision-only px only on
priority: low, taggedestimated). - Hypothesis first, then measure that ROI — never measure globally.
- Box diff is the repair signal; pixel diff is final QA only.
- Every repaired element carries a
data-elbound in the manifest. - Structural copy never ships as generated glyphs — headings, CTA, nav, body, legal and content labels are HTML/CSS text — but non-structural expressive lettering (speech bubbles, signatures, decorative callouts) may ship as a verified transparent raster/SVG
lettering-decalwith exact content proof. DO chase typographic treatment for HTML text (scale steps, tracking, weight, serif accents, mixed-script optical sizing). - Never ship a photo with baked-in text/design — regenerate, stock-replace, or placeholder+ask. No concealment.
- Decide ownership, anchors, and layering before styling (placement ledger + layer plan precede CSS for FV/overlaps).
- Fix the FIRST failing element in document order, then re-render.
- Measure the comp BEFORE implementing; DOMRect-derived numbers are never fidelity evidence.
- The comp's quality lives in its details — every visible device is inventoried and dispositioned.
- Reproduce the motif, not a category stand-in (an outline 「止」 is that kanji, not "some shapes").
- Additions never occlude comp devices; no self-granted waivers.
- A visual's medium is part of the design — photo-class content stays raster; vector drawing only for decorative geometry, flat UI, icons. Do not synthesize a photo/illustration background by drawing SVG/CSS/Canvas/Pillow/HTML and saving it as PNG; that is a prohibited fake asset, not
generated. - Verdicts are judged on rendered pixels via saved crop pairs, never on CSS/DOM inspection.
- Account for the whole frame — the ground/environment is a device with its own inventory row.
- LAYOUT LAW: content lives in flow/Grid/Flex;
position:absoluteonly for declared decorative/overlay layers. - Degraded modes are earned (recorded failed attempt) and reported — never silently assumed.
- Self-scores run ~3 points high — back every score with a crop-pair path.
- FV FIRST: below-FV implementation starts only after the FV gate passes (5.5 tune + fv-critical boxes + impression metrics) — measured-but-unrepaired is the skill's central failure.
- The completion verdict is computed (
completion_gate.py), never narrated — the report headline carries its status; prose may explain aprototype, never promote it to 完了/complete. - Copy is transcribed character-exact from ≥2× zoomed comp crops and re-verified against the build crop — one wrong glyph (field case: comp 実行 shipped as 実装) is a content bug, verdict
missing. - Display typography is run-level. In fv-critical lockups, Latin words, numerals, kana/particles, kanji, units, and emphasized words with different visual size/weight/baseline become span-level manifest elements. Equal CSS
font-sizeis not equal optical size; tune by rendered glyph height and crop pairs. - Contaminated raster backgrounds are regenerated by default. If a raster region has baked-in structural text, logos, functional UI, cards, chips, charts, or foreground elements colliding with copy space, do not crop, blur, mask, or recolor it into service. Regenerate or replace it as a clean background plate first. Rebuild structural copy, controls, live data, and reusable shells as HTML/CSS. Decorative lettering and static screen artwork may stay inside a declared
card_artwork_platewhen they are part of one non-interactive visual composition. - Photo-led regions are declared as photo. Every manifest explicitly sets top-level
photoLed: true|false. A photographic/illustration subject the comp shows (person, product, room, environment) requiresphotoLed: trueplus an fv/section-criticalmediaClass: "photo"/"illustration"row. You may not reclassify it tosvg/ui-mock/css, nor drop it, to slip out of the asset policy —asset_preflight.pyblocksphotoLed: truewith zero critical photo rows, and a non-photo generated asset never satisfies completion gate G8. Replacing a photographic subject with comp-absent invented UI (a dashboard, a chart panel, an empty card) is a fabrication of the rule-13 family and scoresmissing, neveradapted. - Generation is attempted before any fallback. For a photo-led contaminated region, actually invoke the raster image generator and write a file to disk, then verify that path, BEFORE dropping to stock or placeholder. "I couldn't verify a generated asset" is never grounds to skip the attempt — run the generator, then check the file it wrote. Only a recorded, failed generation attempt (tool named, error captured) earns the descent to licensed stock → placeholder+ask.
- The artifact checklist is mandatory and content-bound. Before completion, run
artifact_check.py, pass its output intocompletion_gate.py, and report its status. It records SHA-256 receipts for the manifest/box/scores/reviews, rejects stale review/score order, and must be rerun after any audited input changes. A crop pair must be a readable non-empty file, not merely an existing path. Aneeds_workchecklist (too few crop pairs, FV pixelneeds_workor insufficient comparison coverage, missingmeasurementRef, tolerance override without reason, unchecked generated asset, or missing separate WEB品質/カンプ再現度 scoring) cannot be narrated as complete; ablockedchecklist stops the run until evidence exists. Only Y-only recomposition rows are removed from both pass-rate operands; X/W/H failures remain eligible failures. - The asset preflight is a pre-CSS stop. Every fv/section-critical photo or illustration declares
visualRole,sourceFrameHasForegroundOverlap, andcleanLayeredSource; when overlap is true, listsourceFrameOverlapKinds.crop-assetadditionally provescropPreservesCompositionwithcroppedAssetevidence. Runasset_preflight.py; ifimplementationAllowedis false, do not write CSS for that section. A text-free subcrop of a fused full-field environment is still forbidden when it removes the scene, people, copy-space geometry, or focal relationships that made the comp. - Structural text is not a transformable shape. Headings, labels, CTA, body, dates, and prices default to
transform: none: noscaleX,scaleY, skew, rotation, or visual translation to force a measured bbox. Repair with a class-matched font, weight, size, tracking, leading, run-level sizing, optical punctuation, and flow spacing. Only source-evidenced decorative lettering or unmistakably intentional display distortion may usetypeSpec.transformException; re-render and prove it does not collide.visual-check.mjsblocks undeclared transforms and structural-text overlaps. - Reconstruct the comp's layer topology before styling. Decide whether a photo is a full-frame plate hidden by a foreground mask, a contained photo, a subject cutout over a clean plate, or an object detail tone-merged into a card. Record
photoCompositionMode, the mask/frameclipOwner, card-photo edge treatment, and decorative-field craft. Do not mistake a visible right-side photo for a half-width background, place a section-wide veil outside the rounded frame that owns it, or replace bezier/gradient fields with flat polygons/straight bands. - Multi-frame comps become one web page, not a stack of slides. For every
section-comp, declarepageComposition.sectionswith a content-led height strategy, density role, and bottom-edge/overflow ownership; for every adjacent pair declare an evidenced seam. Runpage_flow_check.pyon rendered section rects. Repeating one fixed height across all sections (especially the source-frame height), clipping every section, or using hard cuts at every seam isneeds_workunless the user explicitly requested that exact uniform treatment and the manifest records the verbatim quote. - Never hide responsive loss with root overflow.
html/body { overflow-x: hidden|clip }is not a fix for fixed-width content. At 320/390/768/1024/1440/1728, every non-decorative meaningful element must remain at least 98% horizontally visible (within 8px), or be an explicitly declared scroll region. Missing same-document fragment targets are hard failures. - Masked pixel evidence must retain enough eligible pixels to mean anything.
pixel_diff.pyreports total/masked/compared pixels and comparison coverage. Default minimum coverage is 50% for pixel-clone and 20% for hybrid/production. In hybrid, generated/replaced FV photo pixels are automatically excluded as intrinsically non-identical and coverage is computed over the remaining eligible pixels. If a verified generated/replaced full-frame plate leaves no pixel-comparable area, the explicit verdict isnot_applicable_generated_media; it clears G3 only while asset policy G9, impression G6, box, crop-pair, and artifact gates pass. All other low coverage isinsufficient_coverage, nevergoodevidence. - Detail inventory is a completion operand, not prose. Hybrid multi-frame manifests carry one machine-readable
detailInventorycovering every section. Every row receives exactly onedisposition.inventoryIdplus readable pair or verbatim waiver. Source-specific devices cannot be mass-labeledadapted;reviewPolicy.maxAdaptedSourceSpecificRatiogates the volume. - Self-review cannot certify itself. Hybrid multi-frame completion requires a different human or agent to review crop pairs only. Record both reviewers, every section score, page score, top gaps, and reviewed pair paths in
section-scores.json.reviewProvenance; the lower score controls and material score deltas return to implementation. - Generated plates do not erase foreground QA. A full-frame generated photo is masked, but opaque source-comparable FV surfaces such as CTA shells may opt into
pixelDiffForeground: truewith a reason. Their boxes are carved back into comparison; structural glyphs stay masked. Model an opaque shell and its text label as separate manifest/DOM rows; a text-bearing bbox cannot serve as a foreground carve-out because the text mask would erase it again. - Requested motion is a contract, not polish prose. When the source asks for motion, set
motion.required: true, preserve the verbatim source quote, limit the plan to one or two comprehension motifs, and runmotion-check.mjsin normal, reduced-motion, and JavaScript-disabled states. Static fidelity is judged in the settled state; motion never hides missing devices or broken CTA destinations. - Specialists are conditionally routed and hash-bound. Hybrid multi-frame work requires a completed
detail-inventory/v1; generated/replaced critical photos also require adoptedphoto-art-direction/v1. Production-only media delivery and interaction QA run only when their explicitproductionReadinessflags are true. Every required report is bound throughspecialistReports; a missing, stale, blocked, or non-passing report stops its parent phase. - Source topology, generation boundaries, and web-surface integration are three separate contracts. Before the raster prompt, classify the source as
section_field,floating_scene,contained_artwork,tone_merged_object, orsource_visible_frame, bind a source crop, and declare all four edge policies. Then chooseassetUnit(full_field_scene_plate,transparent_scene,card_artwork_plate, etc.) and exactly onesurfaceIntegration.mode:alpha_floating,opaque_full_bleed,opaque_masked_merge,opaque_tone_matched, orintentional_frame. A section field cannot be demoted into a centered image card; a floating scene cannot keep an opaque generator background. If CSS owns the card frame/background/padding, the raster must not duplicate them.asset_preflight.pyreads the actual PNG alpha, edge color, uniform outer bands, and estimated content bounds; contradictory pixels return to image generation before CSS. - Large curves have geometry, not just mood. Section-scale waves and seam fields declare
decorativeCraft.geometryPrimitive. Prefer measured bezier paths or an off-canvas true circle with recorded diameter and center. An ellipse requires a source-evidenced exception;width != heightplusborder-radius:50%is not a designed arc by default. - Large decorative lettering is manifested and ordered. Oversized kanji/watermarks need
data-el, inventory binding,zLayer, andmustStayBehindtargets. Unmanifested absolute display glyphs or foreground decoration crossing structural copy fail visual-check. - Japanese line strings are responsive contracts. Critical Japanese headings declare
typeSpec.responsiveLineContractswith expected line strings and forbidden orphan fragments per width range. Validate rendered text-node line clusters, not<br>or span counts. - A hybrid QA pass is pipeline-bound. For multi-frame hybrid work,
visual-check.mjscannot report overall pass unless hash-bound pre-CSS contract-doctor and asset-preflight reports authorize implementation. Responsive integrity may be clean while the fidelity pipeline remains blocked; report both states. - Explicit seamless-scroll intent becomes a cross-section contract. Preserve the verbatim request in
pageComposition.seams[].continuity.sourceRef, invokeseamless-section-waves, and bindspecialistReports.seamContinuity. The bridge must include an opaque destination-owned surface and an incoming next-section preview plus at least one outgoing environment or connective motif layer. Completion requires desktop/mobile seam crops and a passing, image-hash-boundseam-pixel-check/v1; a generic divider, centered ellipse, or boundary-only crop cannot satisfy the request. - A critical heading is an impression geometry, not merely a font label or line count. Every fv/section-critical heading records
typeSpec.sourceImpression: source-frame/block/line/glyph ratios, tracking, line advance, ink density, heading-to-lead/body/label jump ratios, desktop/mobile scale bounds, and evidence crop. Three distinct source frames may not reuse one identical bbox/type signature withoutsharedSystemEvidence. Any fv-critical multi-line structural text (heading or lead) additionally recordstypeSpec.posterGeometry. The browser pass compares these metrics before the section can pass; correct strings with compressed air, extreme weight, timid viewport scale, weak hierarchy, or wrong line widths fail. - Source-specific craft is frozen before CSS. Every
sourceSpecific: trueinventory row carriesrenderingCraft {medium, signatureTraits[>=2], minimumAtomicParts, atomicParts, genericStandInsForbidden:true, evidencePath}.minimumAtomicPartsdescribes the visible internal craft that must survive; it does not automatically require that many DOM nodes or image files. Bind separate manifest rows only when parts behave independently. For one static editorial composition, bind onecard_artwork_plate, list its observedatomicParts, and keep the source-specific relationships inside that clean regenerated plate. A gift-box illustration is not🎁; a listener scene is not repeated👩; a composed device scene is not a Unicode glyph inside a generic white card.contract_doctor.pyblocks missing craft, unexplained raster over-decomposition, and plates that hide their internal craft;visual-check.mjsstill emitsgeneric-symbol-standinwhen sensitive craft collapses into emoji/dingbat-only leaves. - Icon medium follows complexity, not developer convenience. Keep SVG for simple symbolic geometry and native UI controls. A source icon containing a person/pose, facial emotion, organic line character, three or more coordinated subparts, or illustration-specific accents is an
illustration, not a cheap SVG challenge. Generate/adopt a transparent raster in the source style. When three or more icons share one visual family, prefer one receipt-bound chroma-key sprite sheet, verify cell separation and style consistency, remove the key, then extract one transparent PNG per semantic consumer. Never divide a generated sprite byimage_width / expected_countunless pixel evidence proves its cells really follow that grid. Default tosplit_sprite.py: it measures occupied alpha-column clusters, reconciles them to the expected count, crops their real bounds, and blocks when any output cut edge contains alpha. CSS owns the card/frame/padding; generated cells contain only the artwork. - The manifested surface owner must paint visible pixels. Bind
data-elto the<img>,<picture>, or background owner that actually renders a critical raster. Anopacity:0, hidden, or zero-area duplicate cannot stand in for box measurement while another element paints the asset;visual-check.mjsblockssurface-visible-owner. - Preflight binds asset bytes, not only manifest prose.
asset-preflight.json.inputs.assetsrecords every adopted raster path, size, and SHA-256. Changing a PNG without rerunning preflight makes pipeline QA stale. After the first valid pre-CSS pass, an asset revision may re-enter pre-CSS with existing implementation files; never touch/delete files to game chronology. - Topology feedback is a revision, not a CSS exception. Record affected ids, old/new topology, source evidence, invalidated artifacts, and
remeasure_from_source. Regenerate the affected asset and rebaseline its expected bbox from the comp or newly approved reference—never from the current DOMRect. - Small decorative geometry is semantic and executable. Before CSS, write what the mark means and bind
decorativeCraft.microGeometryto the actual primitive/group—not its layout wrapper. A circle gets a measured 1:1 tolerance andflex-shrink:0; a triangle has exactly three vertices; attention rays name their target, side, count, separation, and radial direction. The target center is a direction reference, not the rays' shared origin: rays sit outside the target on an invisible arc and may not overlap it.visual-check.mjsrejects distorted circles, trapezoids, misplaced/shared-origin rays, and wrong ray direction. - Background removal and card-edge contact preserve source semantics. When chroma key or post-generation background removal is used, set
generatedAsset.backgroundRemovalUsed:true, declaresemanticPixelProtectionfor vulnerable sampled colors/features (lips, eyes, badges, status dots), and compare the same-size pre-key sheet with the transparent master before splitting; lost protected pixels block preflight. When source artwork intentionally meets card edges, declaresurfaceIntegration.edgeContactand let the illustration layer reach those edges; position captions independently instead of inheriting generic card padding. - Typography is a measured role graph, and font delivery is part of fidelity. For each section with critical type, measure display/lead/body/label/microcopy relationships in
typographyComposition: glyph/size ratios, weight deltas, line-height/tracking, and negative-space edges (not the CSSwhite-spaceproperty). Preserve deliberately extreme scale instead of tastefully clamping it into the middle. Each critical heading/label also bindstypeSpec.fontSelection: 2+ class-matched candidates with at least one loadable webfont, chosen family/source/real available weight, delivery strategy, and fallback crop. A computed family string is not proof;visual-check.mjsrejects unloaded faces, downgraded weights, flattened hierarchy, collapsed/expanded text-block gaps, and timid dominant scale. A system-only choice needs source-evidenced exception. - Typography geometry resolves to child elements, not a persuasive parent box. Every multi-line fv-critical block lists manifest element ids in
typeSpec.lines; every tuned run lists unique ids inscriptRuns. Those ids must resolve to measured bboxes and rendereddata-elnodes. Numeral/unit pairs such as0円bind the actual adjacent numeral→unit children inrunPairGaps; self-pairs and unrelated pairs are invalid. Vertical labels bindorientation:"vertical"+verticalFlow.render.mjsrecords nearest-owner glyph geometry andvisual-check.mjsrejects line advance, line-start angle, run-gap, tracking, vertical-flow, and glyph-tight per-line bbox drift at the automatically included canonical viewport. - Related diagonals are one measured system. When the comp aligns a lead slant, CTA bevel, and/or display tilt, declare one top-level
geometryRelationships[].kind:"shared-angle"with source angle, tolerance, evidence crop, and measurable members (line-start-axis,clip-path-edge, ortransform-rotation). Do not eyeball each component separately. Every multi-line fv-critical block also declaresposterGeometry.renderReceiptPathandreportPath; runrender.mjswith both--out-pngand--out-rects, thentypography_geometry.py --manifest …soartifact_check.pycan hash-bind the current HTML, every reached local CSS/JS/font/image resource, canonical render, manifest, source image, and passing raster report before completion. The tool is stdlib-only and intentionally excludes glitch/distress/texture judgment. - Source-signature raster texture is explicit, specialist-owned, and content-free. v1 does not auto-detect texture work. Set
rasterTexture {required:true, reason, targetIds}only from a source-signature or explicit user/brand requirement, invokeraster-texture-reconstruction, and bindspecialistReports.rasterTextureasraster-texture-report/v1. Pre-CSS requiresreadyorpass; completion requirespass, current implementation/measurement/exact-size desktop+mobile crop receipts,sourcePixelsShipped:false,contentFreeAsset:true, andstructuralTextRemainsLive:true. Each effect owns its own glyph/element/section coordinate space and CSS/SVG/content-free method, so one target can combine local erosion with lockup-wide glitch bands. The parent still owns DOM semantics, accessibility, responsive QA, independent crop review, and final completion.
Generated background gate
Before implementing any section whose comp uses a photo/illustration background,
write its asset plan into the manifest and follow rules 23–25. The default for a
contaminated raster is regenerate a clean plate (full decision tree in
manifest-and-assets.md):
- Classify the full intended photo field before cropping. Do not inspect only
the rectangle you hope to ship. Set
sourceFrameHasForegroundOverlapagainst the whole environment shown by the comp. If true, a narrower clean crop is not a clean source; use a separate clean layer, regenerate, or replace. - Attempt generation first. A raster generator is usually reachable here
(
cockpit gen-image, a Codex/Firefly image tool, the user's stock account) — invoke one to a file. "I couldn't verify the output" is not grounds to skip the attempt: generate, then verify the file on disk and copy it into"$WORK_ROOT"/assets/withgeneratedAsset {generator, prompt, workspacePath}. A chat preview or tool response is not an asset until the path exists. - Issue the receipt before generation. Save the exact prompt, then run
prompt_receipt.py issue; it refuses an already-existing output. After the generator writes the asset, runprompt_receipt.py adoptand bind that receipt ingeneratedAsset.generationReceipt. A prompt file newer than the output, or a changed prompt/output hash, blocks pre-CSS. - Bind the exact prompt and inputs. Store one UTF-8 exact-prompt file per
adopted critical asset and record its SHA-256.
generatedAsset.promptmust equal that file, not a retrospective summary. Every reference records path, hash, semantic role, and whether it was actually sent to the generator. - Make copy space measurable. A full-frame FV plate declares canonical
copySpaceROIs,subjectZones, and desktop/mobileresponsiveFocalPoints. Prompt prose such as "left 40% clear" is not proof; the ROIs must stay in bounds and copy space may not intersect focal subjects. - Choose full-field scene vs transparent scene before generation. A coupled
hero scene that creates the section world uses
full_field_scene_plateand owns the section edges. A paper object, exploded-layer diagram, device group, or collage that floats on the Web field usestransparent_scene, preserving coupled objects and soft shadows inside alpha while excluding the generator's outer white/paper rectangle. - Only a recorded, failed attempt earns
placeholder(a plain neutral block + blocker note). Never draw a "photo-like" scene in SVG/CSS/Canvas/Pillow and call it generated, and never reclassify the subject tosvg/ui-mock/csswith invented foreground UI (rule 24) — the field escape that shipped a hero as a fake "decision dashboard" and a testimonial as an empty panel. Gate G8 catches missing/reclassified photo media; G9 catches invalid source/crop decisions. - One semantic photo story per source device. If the comp has separate
phone/notebook/recorder scenes, create separate photo rows/assets. A shared
panorama is allowed only with
multiZoneAsset.zones: non-identical crop ROIs, subject signatures, consumers, and final crop-in-use pairs for everydetailInventoryphoto id. A raw whole-plate pair is not integration proof.
"$SKILL_DIR/scripts/skill-pack-python" "$SKILL_DIR/scripts/asset_preflight.py" "$WORK_ROOT/manifest.json" \
--work-root "$WORK_ROOT" --out "$WORK_ROOT/reports/asset-preflight.json"
Layout law (rule 16, expanded)
Measured rects tempt you to copy left/top/width into absolute positioning: the
numbers match at 1440 and the build still fails at every other width (dead
gutter, no reflow). A run that did this scored 30/100 as web design at 29/29 boxes.
- Text, headings, buttons, cards, forms, in-section navigation, CTA groups →
normal document flow, CSS Grid, or Flexbox. Two-column areas are grid/flex
with breakpoints, never fixed left/right coordinates. Global site chrome
(fixed header nav, persistent vertical logo/title, viewport-edge labels) may
be
fixed/stickyonly when the Phase 1 ownership ledger declares it as viewport/global UI and the mobile release behavior is written down. - Sections use a responsive container:
width: min(var(--content-max), 100% - 2*var(--gutter)); margin-inline: auto;. position: absolute/fixed/stickyis allowed only for: layer-plan-declared overlays (background photo layers, overlay gradients), decorative layers (outline watermark type, accent bands, curves), badges pinned to a parent, viewport/global chrome, and true comp overlaps — each declared in the manifest with matchingpositioningand alayerRole. visual-check audits computed CSS against this (layout-lawviolation).- Measured rects are acceptance targets, not implementation instructions.
Reach the target bbox at 1440 by flow means (container width, grid tracks,
gaps, paddings, font metrics). If it matches at 1440 but creates dead
space, overflow, or broken reflow at 320/390/768/1024/1440/1728, it fails the
--widthssweep (Phase 7). - Text bboxes follow the same law: do not apply CSS transforms because a glyph bbox is tall/narrow. A transformed glyph can pass DOMRect geometry while its strokes, counters, baseline, and following-flow clearance are visibly wrong.
Fidelity modes (decide first, record in manifest mode)
| mode | goal | primary signal | typical input |
|---|---|---|---|
pixel-clone | reproduce ONE authoritative comp exactly | box diff → masked pixel diff | hand-made comp, site screenshot |
production | clean production code informed by the comp | box diff on key elements, relaxed | comp + real content/CMS reality |
hybrid | reconstruct the comp's visual language | layer plan + box diff + visual-check + section review | AI-generated comp (the usual case) |
Hybrid is the default for AI comps: photo, type and decoration are fused into one raster — you decompose: background plates are regenerated, replaced, or extracted text-free/UI-free; ALL type and UI are rebuilt in HTML/CSS; stacking is designed explicitly. When text or UI overlaps the photo, the clean background plate comes first, then the foreground DOM layers. Success is judged on FV impression, typographic hierarchy, photo use, layering, responsive integrity, and whether the comp's small devices survived.
Hybrid changes the medium, never the bar. It licenses rebuilding in
different material (HTML type, regenerated photos), not a looser resemblance.
Flow-first recomposition (reordering / taller sections) waives cross-section
y-position only; every element's scale, density, tone, and internal layout are
judged at full strictness. "Hybrid residual" prose is not a license to narrate a
box-4/23 build as complete — completion_gate.py computes the verdict.
Multiple reference images — which case are you in?
- Mood boards / alt comps = visual-language sources: sample from them,
register with
use: "visual-language", reproduce only the primary comp. - A sectioned comp set (ref-01…NN, one image per section of ONE page) =
multi-frame hybrid: register each with
use: "section-comp"+section, normalize ALL frames to one width, set per-elementsourceImage. QA is scoped per frame with the fidelity gradient:- FV frame: near-pixel-strict — judged like a poster comp, full box-diff depth, masked pixel diff.
- Below-FV frames: essence-first, flow-first — reproduce each frame's
essence ledger and internal hierarchy; heights, margins and seams belong
to the executable
pageCompositionplan (Phase 4.5). Frame height is a one-sided density floor (shorter = collapsed = fail; taller = fine), not a target copied into every section. The frames are separately-generated 16:9 slides — their letterbox geometry is a generator artifact, not a design decision. Chasing it yields "half- faithful everywhere, compelling nowhere".
Pipeline (phases × modes × required artifacts)
Environment first: bash "$SKILL_DIR/scripts/setup_env.sh" → prints
SKILL_DIR, script inventory, browser/python status, RECOMMENDED MODE.
$SKILL_DIR = this skill's directory (scripts are NOT in your project).
$WORK_ROOT = output root, default work/; isolate fresh runs
(references/fallbacks.md).
For hybrid multi-frame work, initialize once with the unified runner; it refuses to overwrite an existing run and copies all machine-shaped starters:
"$SKILL_DIR/scripts/skill-pack-python" "$SKILL_DIR/scripts/mockup_pipeline.py" "$WORK_ROOT" --phase init
# at every hand-off between phases:
"$SKILL_DIR/scripts/skill-pack-python" "$SKILL_DIR/scripts/mockup_pipeline.py" "$WORK_ROOT" --phase next
# after measurements, asset decisions, inventory, and specialist reports:
"$SKILL_DIR/scripts/skill-pack-python" "$SKILL_DIR/scripts/mockup_pipeline.py" "$WORK_ROOT" --phase pre-css
pre-css must report implementationAllowed: true before Phase 5 (pass
normally; needs_work only for an asset-policy-earned placeholder). Run the
doctor again with --phase completion after scores exist; it is a shape/policy
gate before, not a replacement for, artifact_check.py and
completion_gate.py.
| # | phase | reference | pixel-clone | production | hybrid |
|---|---|---|---|---|---|
| 0 | normalize frames | measurement.md | req | req | req (every frame) |
| 1 | hypotheses: ownership/anchor ledger, essence, machine-readable detail inventory (+ground row), lettering-vs-HTML copy split, type spec with separate visual-line/run counts, typography specialist report, explicit raster-texture routing decision, bake-off | measurement.md | important els | key els | req |
| 2 | measure bboxes/colors | measurement.md | every important el | key els | FV + section-critical |
| 3 | manifest (+positioning, media class, asset strategy) | manifest-and-assets.md | full | full | full (sparse bboxes OK) |
| 3.25 | contract doctor (shape, ownership, FV line counts, page/photo contract) | manifest-and-assets.md | req | req | req before CSS |
| 3.5 | asset preflight (source overlap, composition, on-disk proof) | manifest-and-assets.md | req for photo/illustration | req | req before CSS |
| 4 | layer plan (+photo edges, decoration craft) | composition.md | where overlap | where overlap | req for FV + overlaps |
| 4.5 | executable page composition plan (pageComposition: section strategies, edge ownership, seams; art-directed continuity when requested) | composition.md | — | — | req multi-frame |
| 4.75 | conditional motion plan (motion.required, max two motifs, settled/reduced/JS-off contract) | composition.md | when requested | when requested | when requested |
| 5 | implement (layout law; FV first) | composition.md | — | — | — |
| 5.5 | FV look-and-tune (eyes before boxes) | composition.md | optional | recommended | req |
| 6 | box loop, desktop+mobile (FV converges before below-FV is built — rule 19) | qa.md | full | critical+high | FV full; below-FV section-critical |
| 7 | visual-check + --widths sweep + computed page flow + inventory dispositions + independent crop-only review (+impression metrics, copy proof, top-5 gaps) + FV gate | qa.md | recommended | required | req — this is the bar |
| 7.5 | motion runtime QA (motion-check.mjs) | qa.md | when requested | when requested | when requested |
| 8 | masked pixel diff | qa.md | req | optional | FV frame req |
| 9 | responsive finish | qa.md | after 8 | after 8 | continuous since 6 |
| 9.25 | completion-shape doctor (section-scores arrays/rows) | qa.md | req | req | req |
| 9.5 | artifact checklist (crop-pair/FV/asset/bbox/report audit) | qa.md | req | req | req |
| 10 | completion gate (computed verdict) | qa.md | req | req | req |
Minimum artifact checklist (hybrid multi-frame) — a missing artifact is a
skipped phase: normalized frames in $WORK_ROOT/mockups/;
reports/hypotheses.md (ownership/anchor ledger, asset plan, lettering-vs-HTML
copy split, essence ledgers, detail inventories ending in the ground row, type
specs with separate visual-line + script/word-run counts, optical-size ratios,
bake-off record, and typography specialist report);
manifest.json; reports/contract-doctor.json with status: pass;
reports/asset-preflight.json with
implementationAllowed: true; background/foreground decomposition +
clean-raster asset review + lettering-decal asset review; layer-plan +
page-composition blocks;
reports/fv-tune/ screenshots;
desktop+mobile renders from the first loop iteration;
--section-relative box report; visual-check + widths-sweep JSON (including
320px and semantic visible-ratio metrics);
reports/page-flow.json plus a readable crop/screenshot for every seam;
hash-bound seam-continuity/v1 plus desktop/mobile crops and
seam-pixel-check/v1 for every explicitly requested art-directed bridge;
hash-bound raster-texture-report/v1 plus desktop/mobile texture crop pairs
when rasterTexture.required=true;
reports/crops/ pairs; reports/section-review.md (FV gate, dispositions
with pair paths, hex pairs, axis-min scores, additions table, page-flow
review, impression-metrics table, copy proof, top-5 visible gaps, separate
WEB品質 and カンプ再現度 self-scores); machine-bound detailInventory
dispositions; reviewProvenance with a different crop-only reviewer;
FV masked pixel diff with comparison coverage; reports/artifact-check.json
with input hash receipts and freshness checks; reports/section-scores.json +
reports/completion-verdict.json (Phase 10).
Specialist routing (invoke only when the condition is present)
Run the deterministic routing matrix in references/specialist-routing.md.
The default specialist chain is inventory → typography/raster texture/photo
direction → implementation → whitespace/motion → media delivery/interaction →
independent visual QA, but every step is conditional. Hash-bind machine reports
through specialistReports; do not invoke a specialist merely because it
exists.
When the environment caps you, spend verification in the evidence-ladder
order (references/fallbacks.md): FV crop pairs → FV box diff + pixel diff →
mobile FV → per-section screenshots + crop pairs → full box loop → widths
sweep. Honest partial evidence + a blocked note beats retrying a dead browser.
The design-quality bar (why Phase 5.5 and 7 exist)
Box convergence cannot see beauty. The rules that carry the "as a website" score
live in composition.md (device craft) and qa.md (impression metrics); the
flags to remember:
- Photo integration — an environment photo never ends in a hard rectangle: bleed / mask-gradient it into the adjacent field, or frame it only if the comp does. Declare each edge.
- Ownership and anchors — fixed headers, viewport-edge vertical logos, hero-bottom watermarks, photo-bound callouts and container content are different implementation objects; preserve the relationship, not just the 1440px rect.
- Decoration craft — a curve is an SVG bezier with the comp's sweep, glass is
blur+translucency+edge light. A straight line for a curve is
missing. - Typography integrity — the source letterform class wins before bbox size; a gothic comp rebuilt in mincho or a non-uniformly scaled heading fails even when box diff is 100%.
- Layer topology — masks/veils clip to the frame that owns them; staggered cards keep their offsets; object photos tone-merge with card fields; CTA portraits use a full plate or plate+cutout when the comp does.
- Look first, measure second — Phase 5.5 tunes the FV visually (2–4 iterations) before the box loop trues up geometry.
- Impression is measured, not vibed — four FV numbers (lockup scale, mixed-
script optical ratios, photo-tone luminance, repeated-device scale+clip) feed
impression-metrics.jsonand gate G6, catching a lockup that shrank,AIgone optically small, a photo gone dark, cards grown 1.4× and clipped. - The page is judged as a page — seams, motif continuity, whitespace rhythm (Phase 4.5 contract, Phase 7 computed page-flow review). Four 8/10 sections can compose a 5/10 page; G10 prevents that page from being called complete.
- A bridge is not a divider — for explicit continuity requests, judge the outgoing field, opaque destination surface, connective motif, and incoming preview in one desktop and one mobile crop. Exact destination color is a pixel contract; the feeling of continuation is a two-section composition.
Browser discipline
ONE browser at a time — parallel launches SIGKILL each other under memory
pressure. render/visual-check hold a launch lock and retry; if they still fail,
walk the transport ladder (do NOT loop retries) and earn any degraded mode with a
recorded failure. Full ladder + no-OpenCV policy: references/fallbacks.md.
Command reference
All scripts under $SKILL_DIR/scripts/; outputs under $WORK_ROOT.
| Script | Purpose |
|---|---|
setup_env.sh | preflight: SKILL_DIR, script inventory, browser/python, recommended mode |
normalize_image.py in.png --width 1440 --out $WORK_ROOT/mockup.png | canonical coordinate space |
profile.py img --axis y [--roi x,y,w,h] | section bands / container edges |
snap_bbox.py img --bbox x,y,w,h [--radius 16] | refine hypothesis bboxes (cv2) |
sample_color.py img --roi x,y,w,h [--exclude …] | measured color tokens |
crop_asset.py img --roi x,y,w,h --out f.png | candidate crop + pixel contamination check; never authorizes adoption; use --purpose evidence-crop only for rendered QA strips |
crop_pair.py --comp f --comp-roi … --build f --build-roi … --out pair.png [--zoom 2] | side-by-side verdict evidence (Pillow-only OK) |
typography_geometry.py --manifest manifest.json --source f --source-roi … --build f --build-roi … --element-id id --out report.json | hash-bound stdlib-only source/build ink bounds, density, every adjacent line advance, and line-start-angle gate; --out must match posterGeometry.reportPath; texture/glitch excluded |
mockup_pipeline.py $WORK_ROOT --phase init|pre-css|completion | non-overwriting setup and ordered gate orchestration; writes reports/pipeline-summary.json |
mockup_pipeline.py $WORK_ROOT --phase next | return one allowed action; reject stale receipts, premature below-FV DOM, missing FV tune/impression, and non-pass completion artifacts |
prompt_receipt.py issue|adopt … | prove the exact prompt existed before generator output and bind prompt/output hashes |
split_sprite.py <transparent-master> --count N --names … --out-dir … --report … | split generated icon sheets by measured alpha clusters; do not assume equal-width cells; block clipped/mixed cut edges |
contract_doctor.py $WORK_ROOT --phase pre-css|completion --out report | stdlib contract preflight: blocks malformed bbox/score containers, global ownership drift, FV line-count freedom, incomplete page/photo contracts before downstream tracebacks |
asset_preflight.py manifest --work-root $WORK_ROOT --out report | pre-CSS gate: rejects fused-source crop reuse, changed composition, missing generation/fallback evidence, invalid alpha/edge-band/color/mask surface integration |
render.mjs --html f --viewport WxH --out-png f --out-rects f | render + DOMRects with render-report/v1 receipts binding current HTML, reached local CSS/JS/font/image files, screenshot, and viewport (locked, retrying) |
box_diff.py manifest rects --out report [--section-relative] | document-order repair signal; reports default vs manifest tolerance provenance; multi-frame REQUIRES the flag |
visual-check.mjs --html f --manifest m --viewports 1440x900,390x844 --out f | intent + typography-transform/overlap verification |
visual-check.mjs … --widths 320,390,768,1024,1440,1728 --out f | responsive integrity + layout-law + visible-ratio + fragment audit |
motion-check.mjs --html f --manifest m --out reports/motion-check.json | conditional normal/reduced/JS-off motion, target, CTA, and manifest-receipt QA |
page_flow_check.py manifest rects --work-root $WORK_ROOT --out reports/page-flow.json | multi-frame Web-native flow gate: height rhythm, section overflow ownership, adjacent seam evidence |
pixel_diff.py mockup rendered --manifest m --out-heatmap d.png | final pixel QA (cv2), including comparison-coverage sufficiency |
artifact_check.py $WORK_ROOT --out reports/artifact-check.json | pre-completion evidence audit: crop pairs, FV coverage, bbox ledger, generated assets, input SHA/freshness, two-track scoring |
completion_gate.py manifest box-report --visual-check … --widths-check … --scores … --artifact-check … --fv-pixel … --impression … --out verdict.json | hash-bound computed completion verdict: complete / prototype / blocked (stdlib-only) |
Failure modes (top; more in each reference)
| Symptom | Fix |
|---|---|
| Content absolutely-positioned to match rects; dead right gutter off-1440 | Layout law: rebuild in flow/grid; rects are targets, not coordinates; run --widths sweep |
responsive-check passes only after adding overflow-x:hidden/clip | root overflow is concealing content; inspect responsive-visible-ratio, fix fixed tracks/breakpoints, and rerun 320–1728 widths |
| Text/UI-contaminated raster crop reused as a background | rule 23: regenerate or replace a clean background plate; rebuild text/cards/charts as DOM layers; crop reuse is missing |
| Adopted crop is text-free only because it excludes the overlapped half of the room/scene | rule 27: set sourceFrameHasForegroundOverlap: true; the crop is forbidden unless a separate clean layered source exists. Regenerate/replace the full composition; G9 blocks completion. |
| Structural copy shipped as a generated lettering image | rule 5: only non-structural decorative callouts/signatures can be lettering-decal; headings/CTA/nav/body/legal stay HTML/CSS |
| Fixed header or vertical logo stuffed into hero flow to match the FV | Phase 1 ownership ledger: classify as viewport-fixed/global UI, manifest positioning: "fixed" or sticky, then preserve responsive behavior |
| Photo-led region reclassified to svg/UI or dropped, then scored "adapted" | rules 24–25: declare it mediaClass: photo, attempt generation to a file first; a removed/reclassified photographic subject is missing, not adapted; gate G8 catches it |
| Generator available but never invoked ("couldn't verify output" → skipped) | rule 25: run the raster generator to a file, then verify; only a recorded failed attempt earns stock/placeholder |
| Prompt file was written after image generation | run prompt_receipt.py issue before the generator and adopt after output; retrospective summaries and stale receipts block pre-CSS |
| Agent draws a photo/illustration with SVG/CSS/Canvas/Pillow and saves PNG | invalid fake asset — delete/reject it; use image generator / licensed stock / owned clean asset / placeholder+ask |
| Many elements fail diff at once | cascade — fix ONLY first_fix, re-render |
box_diff.py crashes because bbox was written as [x,y,w,h] | Start from the hybrid manifest template and run contract_doctor.py --phase pre-css; bbox is always an object {x,y,w,h}. Direct box_diff now emits a blocked JSON report instead of a traceback. |
| Sticky/fixed header outside a section gets a fake section-relative y delta | Declare placementScope: viewport-fixed|viewport-edge, positioning: sticky|fixed, viewport anchor, and mobile behavior; box_diff compares it in viewport-global coordinates. |
| FV heading block suddenly grows after its container narrows | Record typeSpec.expectedVisualLineCount; record expectedRunCount separately when script runs exist. visual-check raises typography-line-count when wrapping changes. |
| FV heading has the right two lines but reads as a dense black lump | Line count is insufficient: measure posterGeometry from the source, compare line bboxes, block-height ratio, line-advance ratio, and signed interline gap on the first render; do not author below-FV DOM until these pass. |
| Parent heading bbox passes but the characters still look small/timid | Run typography_geometry.py on matched source/build ROIs; repair ink bounds/density and per-line widths instead of enlarging the parent or widening tolerance. |
| Source glitch/distress was reduced to generic CSS noise or copied from the comp | Set rasterTexture.required:true, route raster-texture-reconstruction, keep structural text live, rebuild a content-free effect, and bind desktop/mobile crop pairs plus metrics in raster-texture-report/v1. |
0円 or another numeral/unit lockup visually collides | Manifest the numeral and unit as separate scriptRuns, record their source edge gap in runPairGaps, and let typography-run-gap govern margin/spacing. |
| Japanese trainer/title label breaks into several stacked fragments | Use native writing-mode, white-space:nowrap, and measured verticalFlow; manifest each independently styled vertical column rather than only the parent group. |
| Lead text is slightly slanted but CTA bevels use another angle | Bind both through one geometryRelationships shared-angle row; compare line-start-axis to the parsed clip-path edge at canonical width. |
| Box diff passes but page looks nothing like comp | manifest back-filled from own render (rule 9) — re-measure from comp |
| Page reads as stacked slides | Declare pageComposition section strategies + every adjacent seam, make bottom-edge ownership explicit, capture seam evidence, then run page_flow_check.py; equal frame-height slabs trigger W4/G10 |
| FV and next section are separated by a smooth wave but still feel like two slides | source requested continuity → route seamless-section-waves, set seam continuity.required:true, compose outgoing environment + opaque target surface + connective motif + incoming preview, then prove desktop/mobile crops and destination-color samples |
| Specific motif became generic shapes | rule 11; inventory content-level rows; verdict missing |
| Detailed line art/UI/card composites became emoji, dingbats, or one repeated white-card shell | rule 45: freeze renderingCraft traits and atomic parts before CSS; bind the real device rows; generic-symbol-standin is a hard visual-check failure unless the source itself evidences a text glyph |
| Static card art was split into laptop, phone, screens, torus, plinth, and shadows with no independent behavior | rules 38/45: use one card_artwork_plate; keep the outer shell/label in CSS and record observed atomicParts plus keepTogetherReason |
| Hero scene that owns the whole visual field was reduced to a right-side image card and cropped | rule 38: sourceTopology=section_field, generate one full_field_scene_plate with measured copy space, asset-owned bleed and four-edge policy; do not proceed to CSS with the framed asset |
| Paper object, exploded layers, or audience collage sits inside a generator-white rectangle | rule 38: sourceTopology=floating_scene, regenerate one transparent_scene including coupled objects and soft shadow; opaque output returns to image generation |
| Complex people/emotion/object icons look amateurish after hand-authored SVG tracing | rule 46: reclassify composite editorial icons as illustration; generate one style-bound chroma sprite for the family, remove the key, extract transparent consumer PNGs, and keep CSS surface ownership outside the raster |
| A generated sprite was divided into equal widths and an icon is clipped or contains part of its neighbor | rule 46: reject arithmetic slicing unless verified against pixels; run split_sprite.py with the expected count, inspect its measured clusters, and require zero alpha on every output cut edge |
Review says present, render shows it broken | rule 14: crop-pair evidence for every verdict |
| Self 8/10, user 5/10 | rule 18 calibration; re-judge from pairs; independent review if possible |
| Every section scored exactly 7 (the pass bar) | uniform-threshold scoring — gate warning W1; re-judge from pairs with impression metrics in hand |
| box 4/23 + pixel needs_work narrated as "hybrid residual", reported 完了 | rule 20: run completion_gate.py; headline = its status (prototype), list the top-5 visible gaps |
| Comp copy 実行 shipped as 実装; no check fired | rule 21 copy proof: transcribe from ≥2× zoom crop, re-verify glyph-by-glyph against the build crop |
Mixed heading like AI駆動型へ feels wrong though bbox is close | rule 22: split into span-level runs, measure optical height ratios vs anchor kanji, tune size/baseline/tracking |
| Heading passes bbox but looks stretched/condensed and collides below | rule 28: remove structural-text transforms; repeat class-matched font bake-off, then tune size/weight/tracking/leading and flow clearance |
| Organic blue/green field became flat bands or a polygon | record decorativeCraft and reproduce the curve/gradient topology with SVG/CSS gradient or a clean generated decorative raster |
| Staggered photo cards look like identical rows with pasted photos | preserve per-card offsets and cardPhotoIntegration; match card/photo ground tone and dissolve only the comp-visible edges |
| Generated object image already contains a rounded panel, then CSS wraps it in another card | declare assetSurfaceContract; generate one semantic asset per consumer with no baked panel/padding/radius when CSS owns the surface; prove isolated asset + crop-in-use |
| Opaque artwork looks clean alone but creates double padding or a paper-color seam in the card | declare surfaceIntegration; inspect real PNG alpha/outer bands/content bounds/edge RGB. Regenerate as alpha_floating, bleed or mask the plate, tone-match the edge, or preserve a frame only when the source visibly has one |
Manifest calls a source-floating scene contained_artwork after generation because alpha was difficult | source topology is frozen from the comp, not chosen from output convenience; asset preflight blocks the mismatch and returns to generation |
| Oversized background 「聴」 paints over the heading | manifest the glyph with data-el, zLayer, and mustStayBehind; unregistered large absolute text fails visual-check |
| Japanese heading strands 「て」/「へ」/unit on its own line | declare responsiveLineContracts; compare actual rendered line strings and forbidden orphan fragments at each width |
| Rounded framed photo section has a page-wide veil | assign the veil/photo to the frame clipOwner; apply radius/overflow/mask at that owner, not the section root |
| CTA person is cramped into the right half | reclassify the source topology: generate a full-frame plate with copy space, or separate environment + subject cutout when the comp requires independent placement |
| FV measured, residuals logged, below-FV built anyway | rule 19: FV converges first — 3–5 FV-scoped box iterations before any below-FV CSS |
| Requested reveal/flow motion became hover lifts or smooth scroll only | rule 36: record one or two source-backed motifs, test real runtime events, reduced motion and JS-off visibility; broken/placeholder CTA destinations fail motion QA |
| visual-check passes but crop pairs / asset proof / bbox ledger are thin | rule 26: run artifact_check.py; needs_work leads the report, blocked stops completion |
section-scores.json was keyed by section and artifact_check crashed | Copy templates/section-scores.min.json; sections and dispositions are arrays. The completion doctor and downstream gates now return blocked evidence instead of a traceback. |
FV pixel diff says good after masking most of the frame | rule 32: check comparison_coverage; reduce masks or honestly report pixel evidence unavailable |
| Regenerated full-frame hybrid photo yields a meaningless high pixel diff | rerun current pixel_diff.py --manifest; generated/replaced FV photo regions are auto-excluded. A fully regenerated plate reports not_applicable_generated_media and remains bound to asset, impression, crop-pair, box, and artifact gates. |
| Full-frame generated photo makes every foreground device disappear from pixel QA | Mark only opaque source-comparable foreground shells pixelDiffForeground: true; text remains masked. The contract doctor blocks a full-frame generated FV with foreground devices but no carve-out. |
Distinctive dots, icons, arrows, or micro-props all become adapted while the page completes | Bind every Phase 1 row through detailInventory → disposition.inventoryId; the source-specific adaptation ratio and independent crop review prevent blanket simplification. |
| Comp device waived "because the handoff prioritizes X" | self-waiver: waived needs the user's verbatim words |
Per-phase failure modes (hard-rectangle photos, curves→lines, y-waived children,
device-scale clip, mood shift, no-OpenCV, dirty work/, webfont stalls) live in
the reference file for their phase — composition.md, qa.md, fallbacks.md.
Files
references/measurement.md— Phases 0–2 (normalize, hypotheses, inventory, type spec, bake-off, measuring)references/manifest-and-assets.md— Phases 3/3.5 (manifest contract, fonts, media-class asset policy, pre-CSS gate)references/composition.md— Phases 4/4.5/5/5.5 (layers, photo edges, decoration craft, page plan, FV tune)references/qa.md— Phases 6–9 (box loop, visual-check, section review, verdicts & scoring, pixel diff, responsive)references/fallbacks.md— setup, WORK_ROOT isolation, no-OpenCV, browser ladder, evidence ladder, completion reportreferences/specialist-routing.md— conditional specialist triggers, ordering, report contracts, and skip rulesreferences/fv-poster-example.md— worked hybrid FV exampletemplates/— base.css, poster-typography.css, hypotheses.md, section-review.md, photo-asset-review.md,manifest.hybrid-multiframe.min.json,section-scores.min.jsonschemas/element_manifest.schema.json— manifest contract (incl.positioning,layerRole,qaPriority, asset fields)VALIDATION.md— per-version field feedback and test evidence
What ships with it: 68 files
1309.0 KB alongside SKILL.md, 44 of them executable
archive/
- SKILL-v6.md67.4 KB
references/
- composition.md29.4 KB
- fallbacks.md8.6 KB
- fv-poster-example.md7.0 KB
- manifest-and-assets.md35.6 KB
- measurement.md23.9 KB
- qa.md44.1 KB
- specialist-routing.md7.6 KB
schemas/
- element_manifest.schema.json84.1 KB
scripts/
- artifact_check.pyruns55.3 KB
- asset_preflight.pyruns38.7 KB
- box_diff.pyruns15.3 KB
- _box_quality.pyruns3.4 KB
- _browser.mjsruns6.0 KB
- completion_gate.pyruns28.5 KB
- contract_doctor.pyruns139.8 KB
- crop_asset.pyruns6.4 KB
- crop_pair.pyruns3.9 KB
- _imgcompat.pyruns3.4 KB
- install_skill_pack.pyruns16.2 KB
- install-skill-pack.shruns152 B
- mockup_pipeline.pyruns20.2 KB
- motion-check.mjsruns7.7 KB
- normalize_image.pyruns1.6 KB
- page_flow_check.pyruns19.6 KB
- pixel_diff.pyruns10.3 KB
- profile.pyruns4.2 KB
- prompt_receipt.pyruns4.1 KB
- render.mjsruns8.4 KB
- sample_color.pyruns3.1 KB
- setup_env.shruns8.3 KB
- skill-pack-pythonruns135 B
- snap_bbox.pyruns4.7 KB
- split_sprite.pyruns6.0 KB
- surface_pixels.pyruns9.7 KB
- typography_geometry.pyruns19.2 KB
- .gitignore160 B
- LICENSE758 B
- package.json1.0 KB
- README.md5.5 KB
28 more files not listed here. See all 68 in the repository.
Gives 0 of the 12 instructions most design frontend skills give in ~13.9k tokens
Counted across 1,169 of the 1,878 authors here whose files we hold, read 2026-08-07
- Use CSS variables for color consistencyin 72 of 1169, across 23 files
- Commit to one bold aesthetic direction before codingin 72 of 1169, across 27 files
- Match implementation complexity to the aesthetic visionin 70 of 1169, across 20 files
- Add atmospheric background effects and texturesin 57 of 1169, across 9 files
- Use unexpected spatial compositions and layoutsin 56 of 1169, across 8 files
- Implement real working codein 55 of 1169, across 7 files
- Vary themes and aesthetics across different designsin 48 of 1169, across 7 files
- Launch chromium in headless modein 47 of 1169, across 4 files
- Close the browser when donein 47 of 1169, across 4 files
- Run provided scripts with help flag firstin 47 of 1169, across 4 files
- Wait for network idle statein 47 of 1169, across 4 files
- Use descriptive selectors for elementsin 47 of 1169, across 4 files
Said here and by no other author read
- Measure regions instead of estimating globally
- Use box diff as the repair signal
- Build layout with flow, grid, or flex
- Pass the first view gate before below-fold CSS
- Transcribe text character-exact from zoomed crops
- Attempt raster generation before using fallback assets
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.