feat(ai-skills): aesthetic-hygiene rules in layout.md (preventive, not just curative)

Why: the 6 aesthetic detectors added in 53435bf7 / 7aef1b14 / cd1e4325 /
ad025c95 catch problems AFTER the model emits them. Telling the model
upfront — in the always-loaded layout skill — prevents the same patterns
in the first place. Cheaper than running a corrective post-pass on
every generation, and the model produces cleaner output that doesn't
trip the detectors at all.

What: AESTHETIC HYGIENE block appended to layout.md (priority 10, base,
loaded for every generation). 4 rules each backed by a corresponding
detector:

- Text never gets cornerRadius / stroke / effects / rotation. Mirrors
  detectTextCornerRadius / detectTextStroke / detectTextEffect.
- Rotation on UI frames is almost always wrong. Mirrors
  detectUnexpectedRotation (with the same 90/180/270 + path/line/polygon
  /image escape hatches).
- Same-role siblings must share cornerRadius AND padding. Mirrors
  detectMixedSiblingCornerRadius / detectMixedSiblingPadding.
- Inner layout frames (sections, wrappers) inherit from page/card —
  only opt into fill/stroke/shadow on the outer card/button/badge/chip.
  Mirrors the existing invisible-container detector.

Phrased as a "keep these silent" pre-condition since the post-pass
also strips them. 1080/1080 AI tests + 234/234 pen-ai-skills tests
still pass.
This commit is contained in:
Fini 2026-05-09 21:28:00 +08:00
parent 8475797c7f
commit 5a94c22c8e

View file

@ -88,3 +88,17 @@ RING / CIRCLE WITH CENTER CONTENT (Apple Activity Ring, progress ring, badge, av
flex layout instead.
- textAlignVertical is NOT supported. Use a layout=horizontal/vertical parent + alignItems=center
- justifyContent=center to center text inside any container.
AESTHETIC HYGIENE — keep these silent (never emit, the post-pass also strips them):
- TEXT NODES NEVER GET: cornerRadius, stroke, effects, rotation. Text is filled glyphs — clip /
border / shadow / tilt all come out wrong on canvas. (Stroke is for icon-font nodes only.)
- ROTATION on UI frames is almost always wrong. Use rotation=0 (or omit) on cards / buttons /
containers / labels. The only legitimate rotations are exact 90 / 180 / 270 (vertical text /
rotated grid) and rotation on path / line / polygon / image (decorative geometry).
- SAME-ROLE SIBLINGS MUST USE THE SAME cornerRadius AND padding. Three cards in a row at
cornerRadius 8 / 8 / 12 reads as ragged. Pick one value per group and reuse it. Same for
padding — 16 / 16 / 20 across cards is visible noise.
- INNER LAYOUT FRAMES (sections, wrappers, header / body containers inside a card) DO NOT need
fill, stroke, OR shadow. They inherit from the page / card surface. Only opt into a fill /
border / shadow on the OUTER card, button, badge, chip — NEVER on the wrapper that holds it.