feedback1 final: the loadout screen's background layer draws again (pointed out in PR #14)

css/screens/loadout.css: `.lo > * { position: relative }` (one class, a later rule) overrode `.lo__bg { position:
absolute }`, so the mint glow / grid layer was a 0-px flex item and never rendered. `.lo > :where(:not(.lo__bg))`
keeps the one-class specificity for every other layer and never matches the background.

Checked in headless Chrome at 1920x1080 and 844x390 (touch): the layer now covers the overlay (0 px tall before),
every other box of the screen is unchanged, no console errors. Tests: test/ui/loadout.test.js (the cascade; fails on
the old rule), opt-in test/ui/loadout.e2e.test.js (the layer's box and stacking at both sizes). DESIGN §21.25 credits
PR #14 and PR #10 (crossOrigin on the two new Image() loads); CHANGELOG 0.1.1 lines for both.
This commit is contained in:
sganggs committed 2026-10-03 19:17:27 +08:00
1 parent 2dba6da598
commit e7d957b27c
5 files changed
+42 -2

No files matched your search

+3 -1
View File
@@ -1406,10 +1406,12 @@ Not done (noted, no primary source or out of scope): whether 华法琳 S2's 流
- **QA after the integration, fixed**: rule 3 counted only the board pieces that were not removed, but a summon leaves its home free only once it has expired or been killed (a docked one keeps its tile reserved), so the 召唤物 clause never applied — a 突袭 member that landed on the home of 浊心斯卡蒂's expired 海嗣 and fell there lay on it and kept the 海嗣 (远古血亲) from coming back. Every board piece's home counts now, on the field or not. Cost: the body bookkeeping added about 2.5 % per tick on 519 real specs (8 % on boss fields; whole matches and the perf budgets unchanged); `_checkRedeploys` now checks the DP before the tile scans, so an operator waiting for DP costs no ally scan — on the same 519 specs, against the integration head, the same tick counts and boss fields 11.9 → 10.9 µs per tick (a tile → body map is left for later).
- [ASSUMED]: §21.20. Tests: `test/sim/feedback1f-downed-tile.test.js` (rule 3 for a summon that has expired or been killed), `test/render/feedback1f-down-tile.test.js`, opt-in `test/render/feedback1f-down-tile.browser.test.js`; `downelem`, `bonds_addon`, `engine-requests`, `robustness` follow the rule.
### 21.25 Hardening credited to pull requests (PR #2, PR #7) — `match/effectsMeta.js dispatch / stillEquipped`, `tools/fetch-assets.mjs shrinkGuard`, `tools/assets/manifest.mjs droppedEntries`
### 21.25 Hardening credited to pull requests (PR #2, PR #7, PR #10, PR #14) — `match/effectsMeta.js dispatch / stillEquipped`, `tools/fetch-assets.mjs shrinkGuard`, `tools/assets/manifest.mjs droppedEntries`, `assets.js loadImageElement`, `ui/guide.js preload`, `css/screens/loadout.css`
- **The prep dispatcher's equipped items** (pointed out in PR #2, whose 突变细胞 bench rule §21.1 now follows — official footage confirmed it —, its merge path excepted): step 5 iterated `holder.items` live while handlers move and destroy pieces — normal 博士投影 destroys itself at the round start (the splice skipped the next item on that holder), 突变细胞 transforms its holder (the next item ran with a holder that was gone). It now walks a snapshot of the owned chess and of each holder's items and runs an item only while it is still equipped on its still-owned holder; a piece gained or equipped meanwhile waits for the next dispatch (effectsMeta header, META §2.2). No shipped item has a second hook on those events, so play is unchanged; a synthetic spy handler pins the rule (`test/match/feedback1-dispatch-snapshot.test.js`). QA after the integration: the items were read per holder as the walk reached it, so an item equipped meanwhile onto a holder not yet walked ran in the same dispatch and an item moved to a later holder ran twice (latent: no shipped item equips or moves items on those hooks); every [holder, item] pair is now taken before the first item runs, and two more synthetic cases pin it.
- **fetch-assets never shrinks the committed manifest by accident** (pointed out in PR #7, whose `data/assets.json`, regenerated on a machine where some downloads failed, was 42 audio entries short — all 42 still resolve upstream): a rebuilt manifest leaves out every entry whose files are missing on that machine. When it would lose an entry of the current `data/assets.json`, the run keeps the current file, prints the entries it would drop (also the report's `droppedEntries` / `manifestWritten`) and exits 1; `--allow-shrink` (or `--prune`) writes it (ASSETS.md; `test/fetch-assets-shrink.test.js`).
- **crossOrigin on the two `new Image()` loads** (PR #10, merged on GitHub): with `/assets/` served from another origin (a CDN or object storage) an image loaded without CORS approval taints the canvas and breaks the WebGL textures (an empty map, a white 3D board). `assets.js loadImageElement` — the asset store's only image path, §21.27's seeded store included — and `ui/guide.js preload` set `crossOrigin = 'anonymous'`; a same-origin page is unaffected.
- **The loadout screen's background layer** (pointed out in PR #14): `css/screens/loadout.css` `.lo > * { position: relative }` — one class, a later rule — overrode `.lo__bg { position: absolute }`, so the mint glow and grid layer was a 0-px flex item and never drew. Now `.lo > :where(:not(.lo__bg))`: the same one-class specificity for every other layer, never the background. Checked in headless Chrome at 1920×1080 and 844×390 (touch): the layer covers the overlay and every other box of the screen is where it was (to 0.1 px). Tests: `test/ui/loadout.test.js` (the cascade), opt-in `test/ui/loadout.e2e.test.js` (`SP_E2E=1`: the layer's box and stacking at both sizes).
### 21.26 Gaps found while triaging GitHub issues #1 / #8 (v0.1.1)