openpencil/apps/web/src
Fini ec4fe44368 feat(pen-core): strip nested card-style decoration on inner frames
User-reported 2026-05-11 "Popular Restaurants" — inspecting the live
canvas via batch_get showed the LLM built each row as
`role:card` (outer) carrying stroke + cornerRadius:16 + 2-shadow
elevation, then nested an inner `Card Info` frame ALSO with
`role:card`, cornerRadius:12, and the SAME 2-shadow stack for the
right-hand text column. The doubled decoration rendered as a
visible "border" / box-in-box that the user called out as the
N-tools being "死板" — element-builders deterministically emit
their own card decoration without knowing they're being nested.

New post-pass `stripNestedCardDecoration` walks the page tree and,
for each non-protected frame:
  - if the frame has stroke AND any frame ancestor has stroke   → strip stroke
  - if the frame has cornerRadius > 0 AND any frame ancestor
    has cornerRadius > 0                                        → strip cornerRadius
  - if the frame has shadow AND any frame ancestor has shadow   → strip effects

Each decoration type is checked independently so e.g. a card inside
a shadow-only ancestor still keeps its cornerRadius. Fills are NOT
touched — stripRedundantSectionFills already handles fill heuristics
and a child fill may be an intentional surface change (dark accent
strip inside a white card).

KEEP_DECORATION_ROLES exempts elements that legitimately carry their
own affordance even when nested in a card: button, chip, search-bar,
input, badge, avatar, switch, etc. Those keep their click-target
visual whether or not the parent is decorated.

Wired in apps/web design-canvas-ops.ts at both finalize sites,
running AFTER stripRedundantSectionFills so the fill pass gets first
crack and this pass cleans up the leftover stroke/cornerRadius/
shadow stack.

Tests: 8 cases — basic strip, partial strip (only matched types),
top-level decoration preserved, protected-role exemption, fills
untouched, deep nesting, asymmetric cornerRadius arrays, no-op
return value.
2026-05-11 00:17:02 +08:00
..
__tests__ V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
canvas feat(pen-core): strip nested card-style decoration on inner frames 2026-05-11 00:17:02 +08:00
components Merge origin/v0.8.0 into feat/rust-ification 2026-05-03 21:00:00 +08:00
constants V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
hooks V0.7.3 (#111) 2026-04-15 22:19:12 +08:00
i18n V0.7.1 (#102) 2026-04-13 21:30:23 +08:00
lib fix(ai): refresh DeepSeek defaults to v4 model series 2026-04-26 06:29:53 +08:00
routes V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
services feat(pen-core): strip nested card-style decoration on inner frames 2026-05-11 00:17:02 +08:00
stores Merge origin/v0.8.0 into feat/rust-ification 2026-05-03 21:00:00 +08:00
types V0.7.2-bugfix (#109) 2026-04-14 21:42:56 +08:00
uikit V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
utils Merge branch 'v0.8.0' of github.com:ZSeven-W/openpencil into v0.8.0 2026-05-05 22:51:00 +08:00
variables V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
router.tsx V0.7.0 (#95) 2026-04-11 23:25:13 +08:00
routeTree.gen.ts V0.5.0 (#67) 2026-03-22 09:44:04 +08:00
styles.css V0.7.0 (#95) 2026-04-11 23:25:13 +08:00