feat: настроить визуальный стиль лестниц (#683)

Issue: #683
User-Visible: yes
This commit is contained in:
Sergey Matyunin
2026-09-27 23:04:28 +03:00
parent cf01489fa9
commit 5b5b808184
31 changed files with 554 additions and 93 deletions
+8 -1
View File
@@ -367,8 +367,15 @@ export const LOW_HEADROOM_WARNING_BYTES = 15_000;
* чистой площади нужны непосредственно в View. Placement, transform и
* properties вынесены в lazy editor; общий бюджет 301 066 Б не меняется.
* Центр оставляет 978 Б сверху и 1 022 Б до нижней границы полосы.
*
* 2026-09-27, #683: 299 700 → 300 200 (замер 299 638). Разрешение сохранённых
* цветов лестницы, CSS-переменные её символа и геометрия трапеции/равных
* ступеней нужны обоим View-renderer'ам до загрузки редактора; сами два
* color-picker и запись свойств остаются в lazy editor. Новый центр оставляет
* 562 Б сверху и 1 438 Б до нижней границы полосы. Общий бюджет 301 066 Б не
* меняется; малый остаток продолжает печататься отдельным предупреждением.
*/
export const INITIAL_VIEW_GZIP_CEILING = 299_700;
export const INITIAL_VIEW_GZIP_CEILING = 300_200;
export const INITIAL_VIEW_CEILING_BAND = 2_000;
/**
+1 -1
View File
@@ -4,5 +4,5 @@
"hostRefs": 4880,
"portPrivates": 94,
"harnessPrivates": 100,
"bundleBytes": 2577881
"bundleBytes": 2581147
}
+28 -4
View File
@@ -228,12 +228,36 @@ const MUTANT_DEFINITIONS = [
id: 'stairs-tread-count-depends-on-render-scale',
guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs '
+ '&& node --test test/stairs.test.mjs',
because: '#663 AC3: 30 cm is a physical interval; viewport scale may change pixels but '
+ 'must not change the number or placement of treads.',
because: '#683 AC6: the equal interval nearest 30 cm is physical; viewport scale may '
+ 'change pixels but must not change the number or placement of treads.',
patches: [{
file: 'src/stairs.ts',
find: ' const treadN = cmToNorm(STAIR_TREAD_CM, cellCm);\n',
replace: ' const treadN = cmToNorm(STAIR_TREAD_CM, cellCm) * NORM_W / scale; // mutant\n',
find: ' const count = stairIntervalCount(stair.length * cellCm * GRID_N);\n',
replace: ' const count = stairIntervalCount(stair.length * cellCm * GRID_N * NORM_W / scale); // mutant\n',
}],
},
{
id: 'stairs-legacy-save-keeps-implicit-style',
guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs '
+ '&& node --test --test-name-pattern=legacy test/stairs.test.mjs',
because: '#683 AC8: reading a legacy stair stays non-mutating, but its first explicit Save '
+ 'must materialize the complete visual quartet so the result no longer follows global defaults.',
patches: [{
file: 'src/stairs.ts',
find: ' fill_opacity: resolved.fillOpacity,\n',
replace: ' fill_opacity: 0, // mutant: one explicit field is not materialized\n',
}],
},
{
id: 'stairs-active-link-loses-pointer-cursor',
guard: 'npx tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs '
+ '&& node --test --test-name-pattern=cursor test/stairs.test.mjs',
because: '#683 AC12: only a stair with an active floor target promises navigation with the '
+ 'standard pointer cursor; removing it makes the clickable symbol look inert.',
patches: [{
file: 'src/styles/plan.styles.ts',
find: ' .hp-stair.navigable { cursor: pointer; }\n',
replace: ' .hp-stair.navigable { cursor: default; } /* mutant */\n',
}],
},
{