diff --git a/app/config/architecture-inventory.json b/app/config/architecture-inventory.json index bf5f700..19c9aff 100644 --- a/app/config/architecture-inventory.json +++ b/app/config/architecture-inventory.json @@ -314,8 +314,8 @@ }, { "path": "frontend/styles/redesign-v2.css", - "bytes": 262826, - "lines": 8554 + "bytes": 262113, + "lines": 8533 }, { "path": "frontend/index.html", diff --git a/app/frontend/styles/design-system.css b/app/frontend/styles/design-system.css index dcc452c..875ccc7 100644 --- a/app/frontend/styles/design-system.css +++ b/app/frontend/styles/design-system.css @@ -771,7 +771,6 @@ tbody tr.clickable{cursor:pointer} [data-active-view="auctionView"], [data-active-view="themeLibraryView"], [data-active-view="popularityView"], - [data-active-view="dragonView"], [data-active-view="mentorView"], [data-active-view="rotationView"] ) .app-main{ @@ -786,7 +785,6 @@ tbody tr.clickable{cursor:pointer} [data-active-view="auctionView"], [data-active-view="themeLibraryView"], [data-active-view="popularityView"], - [data-active-view="dragonView"], [data-active-view="mentorView"], [data-active-view="rotationView"] ) .overview-strip{flex:0 0 auto} @@ -795,7 +793,6 @@ tbody tr.clickable{cursor:pointer} [data-active-view="auctionView"], [data-active-view="themeLibraryView"], [data-active-view="popularityView"], - [data-active-view="dragonView"], [data-active-view="mentorView"], [data-active-view="rotationView"] ) .workspace-view.active-view{ @@ -807,7 +804,6 @@ tbody tr.clickable{cursor:pointer} #auctionView.active-view, #themeLibraryView.active-view, #popularityView.active-view, - #dragonView.active-view, #mentorView.active-view{display:flex;flex-direction:column} #rotationView.active-view{ @@ -827,7 +823,6 @@ tbody tr.clickable{cursor:pointer} #themeLibraryView .theme-summary-v2, #popularityView .popularity-page-head-v2, #popularityView .popularity-glance-v2, - #dragonView .dragon-page-head-v2, #mentorView .mentor-page-header, #mentorView .member-gate, #mentorView #mentorNotice{flex:0 0 auto} @@ -835,7 +830,6 @@ tbody tr.clickable{cursor:pointer} #auctionView .auction-workspace-v2, #themeLibraryView .theme-library-workspace-v2, #popularityView .popularity-table-card-v2, - #dragonView .dragon-daily-content-v2, #mentorView .mentor-layout{min-height:0;flex:1 1 auto} #auctionView .auction-workspace-v2{height:100%;grid-template-columns:minmax(0,1fr) var(--right-rail-wide);grid-template-rows:minmax(0,1fr);align-items:stretch;overflow:hidden} @@ -853,10 +847,6 @@ tbody tr.clickable{cursor:pointer} #popularityView .popularity-table-card-v2{display:flex;flex-direction:column;overflow:hidden} #popularityView .popularity-table-frame-v2{min-height:0;flex:1 1 auto;overflow:auto} - #dragonView .dragon-daily-content-v2{overflow:hidden} - #dragonView .dragon-trader-detail-v2{min-height:0} - #dragonView .dragon-trader-detail .trader-operations{min-height:0;overflow:auto} - #mentorView .mentor-layout{height:auto;overflow:hidden} #mentorView .mentor-sidebar, #mentorView .mentor-chat-panel, diff --git a/app/frontend/styles/redesign-v2.css b/app/frontend/styles/redesign-v2.css index 56f8eef..5948eb6 100644 --- a/app/frontend/styles/redesign-v2.css +++ b/app/frontend/styles/redesign-v2.css @@ -4350,17 +4350,11 @@ body.sidebar-collapsed .status-bar { left: 64px; } .dragon-empty-actions-v2 .lucide { width: 15px; height: 15px; } @media (min-width: 721px) { - body[data-active-view="dragonView"] .app-main { display: flex; flex-direction: column; overflow: hidden; } - body[data-active-view="dragonView"] .overview-strip { flex: 0 0 auto; } + body[data-active-view="dragonView"] .app-main { height: var(--workspace-height); min-height: 0; display: block; overflow: auto; } body[data-active-view="dragonView"] #dragonView.active-view { - min-height: 0; - flex: 1 1 auto; - display: flex; - flex-direction: column; + display: block; + overflow: visible; } - body[data-active-view="dragonView"] .dragon-page-head-v2 { flex: 0 0 auto; } - body[data-active-view="dragonView"] .dragon-daily-content-v2, - body[data-active-view="dragonView"] .dragon-empty-state-v2 { flex: 1 1 auto; } } @media (min-width: 721px) and (max-height: 900px) { @@ -8372,40 +8366,25 @@ body.sidebar-collapsed .status-bar { left: 64px; } white-space: nowrap; } -/* The Dragon-Tiger page stays still; only the selected trader's operations scroll. */ +/* The Dragon-Tiger page owns vertical scrolling; wide operation tables scroll horizontally. */ @media (min-width: 721px) { body[data-active-view="dragonView"] .dragon-daily-content-v2 { - min-height: 0; - display: grid; - grid-template-rows: auto auto auto minmax(150px, 1fr) auto; - overflow: hidden; - } - - body[data-active-view="dragonView"] #dragonView .dragon-card-stage-v2 { - flex: 0 0 auto; + display: block; + overflow: visible; } body[data-active-view="dragonView"] #dragonView .dragon-trader-detail-v2 { - min-height: 0; - display: flex; - flex-direction: column; - } - - body[data-active-view="dragonView"] #dragonView .dragon-detail-header { - flex: 0 0 auto; + display: block; } body[data-active-view="dragonView"] #dragonView .dragon-trader-detail .trader-operations { - min-height: 0; - flex: 1 1 auto; + max-height: none; overflow: auto; - overscroll-behavior: contain; - scrollbar-gutter: stable; } body[data-active-view="dragonView"] #dragonView .dragon-unclassified-v2 { - max-height: 180px; - overflow: auto; + max-height: none; + overflow: visible; } :is( diff --git a/app/tests/e2e/app-shell.spec.js b/app/tests/e2e/app-shell.spec.js index e377bb4..39a3489 100644 --- a/app/tests/e2e/app-shell.spec.js +++ b/app/tests/e2e/app-shell.spec.js @@ -1400,25 +1400,31 @@ test("dragon-tiger redesign keeps the merged empty state and independent card hi await expect(page.locator("#stockDialog")).toBeVisible(); await page.locator("#closeStockDialog").click(); + await page.setViewportSize({ width: 1366, height: 768 }); const scrollOwnership = await page.evaluate(() => { const body = document.querySelector("#dragonTraderDetail tbody"); const seed = body.querySelector("tr"); for (let index = 0; index < 20; index += 1) body.appendChild(seed.cloneNode(true)); + const main = document.querySelector(".app-main"); const daily = document.querySelector("#dragonDailyContent"); const operations = document.querySelector("#dragonTraderDetail .trader-operations"); return { + mainOverflow: getComputedStyle(main).overflowY, + pageScrolls: main.scrollHeight > main.clientHeight, dailyOverflow: getComputedStyle(daily).overflowY, dailyFits: daily.scrollHeight <= daily.clientHeight + 1, operationOverflow: getComputedStyle(operations).overflowY, - operationsScroll: operations.scrollHeight > operations.clientHeight, + operationsFit: operations.scrollHeight <= operations.clientHeight + 1, descriptionSize: parseFloat(getComputedStyle(document.querySelector("#dragonTraderDetail .dragon-detail-header p")).fontSize), }; }); expect(scrollOwnership).toEqual({ - dailyOverflow: "hidden", + mainOverflow: "auto", + pageScrolls: true, + dailyOverflow: "visible", dailyFits: true, operationOverflow: "auto", - operationsScroll: true, + operationsFit: true, descriptionSize: 13, }); diff --git a/app/tests/preservation_helpers.py b/app/tests/preservation_helpers.py index edb431c..1c20683 100644 --- a/app/tests/preservation_helpers.py +++ b/app/tests/preservation_helpers.py @@ -151,6 +151,106 @@ AUDITED_CSS_RETIREMENTS = { ), } +# User-approved product behavior changes remain separate from code-retirement +# records. Each entry is an exact source/replacement pair. Optional trailing +# values declare the expected source count and how many leading occurrences to +# transform when one identical occurrence must remain. +AUDITED_CSS_REPLACEMENTS = { + "redesign-v2.css": ( + ( + ( + '@media (min-width: 721px) {\n' + ' body[data-active-view="dragonView"] .app-main { display: flex; flex-direction: column; overflow: hidden; }\n' + ' body[data-active-view="dragonView"] .overview-strip { flex: 0 0 auto; }\n' + ' body[data-active-view="dragonView"] #dragonView.active-view {\n' + ' min-height: 0;\n' + ' flex: 1 1 auto;\n' + ' display: flex;\n' + ' flex-direction: column;\n' + ' }\n' + ' body[data-active-view="dragonView"] .dragon-page-head-v2 { flex: 0 0 auto; }\n' + ' body[data-active-view="dragonView"] .dragon-daily-content-v2,\n' + ' body[data-active-view="dragonView"] .dragon-empty-state-v2 { flex: 1 1 auto; }\n' + '}\n' + ), + ( + '@media (min-width: 721px) {\n' + ' body[data-active-view="dragonView"] .app-main { height: var(--workspace-height); min-height: 0; display: block; overflow: auto; }\n' + ' body[data-active-view="dragonView"] #dragonView.active-view {\n' + ' display: block;\n' + ' overflow: visible;\n' + ' }\n' + '}\n' + ), + ), + ( + ( + "/* The Dragon-Tiger page stays still; only the selected trader's operations scroll. */\n" + '@media (min-width: 721px) {\n' + ' body[data-active-view="dragonView"] .dragon-daily-content-v2 {\n' + ' min-height: 0;\n' + ' display: grid;\n' + ' grid-template-rows: auto auto auto minmax(150px, 1fr) auto;\n' + ' overflow: hidden;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-card-stage-v2 {\n' + ' flex: 0 0 auto;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail-v2 {\n' + ' min-height: 0;\n' + ' display: flex;\n' + ' flex-direction: column;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-detail-header {\n' + ' flex: 0 0 auto;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail .trader-operations {\n' + ' min-height: 0;\n' + ' flex: 1 1 auto;\n' + ' overflow: auto;\n' + ' overscroll-behavior: contain;\n' + ' scrollbar-gutter: stable;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-unclassified-v2 {\n' + ' max-height: 180px;\n' + ' overflow: auto;\n' + ' }\n' + ), + ( + '/* The Dragon-Tiger page owns vertical scrolling; wide operation tables scroll horizontally. */\n' + '@media (min-width: 721px) {\n' + ' body[data-active-view="dragonView"] .dragon-daily-content-v2 {\n' + ' display: block;\n' + ' overflow: visible;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail-v2 {\n' + ' display: block;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-trader-detail .trader-operations {\n' + ' max-height: none;\n' + ' overflow: auto;\n' + ' }\n\n' + ' body[data-active-view="dragonView"] #dragonView .dragon-unclassified-v2 {\n' + ' max-height: none;\n' + ' overflow: visible;\n' + ' }\n' + ), + ), + ), + "design-system.css": ( + (' [data-active-view="dragonView"],\n', "", 4, 3), + (' #dragonView.active-view,\n', ""), + (' #dragonView .dragon-page-head-v2,\n', ""), + (' #dragonView .dragon-daily-content-v2,\n', ""), + ( + ' #dragonView .dragon-daily-content-v2{overflow:hidden}\n' + ' #dragonView .dragon-trader-detail-v2{min-height:0}\n' + ' #dragonView .dragon-trader-detail .trader-operations{min-height:0;overflow:auto}\n\n', + "", + ), + ), +} + def sha256(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() @@ -245,12 +345,21 @@ def assert_moved_asset_matches( frontend_relative: str | None = None, ) -> None: target_relative = frontend_relative or original_relative - if original_relative in AUDITED_CSS_RETIREMENTS: + if ( + original_relative in AUDITED_CSS_RETIREMENTS + or original_relative in AUDITED_CSS_REPLACEMENTS + ): original = (ORIGINAL_STATIC / original_relative).read_text(encoding="utf-8") - for retired in AUDITED_CSS_RETIREMENTS[original_relative]: + for retired in AUDITED_CSS_RETIREMENTS.get(original_relative, ()): source, replacement = retired if isinstance(retired, tuple) else (retired, "") testcase.assertEqual(original.count(source), 1, source) original = original.replace(source, replacement, 1) + for replacement in AUDITED_CSS_REPLACEMENTS.get(original_relative, ()): + source, target, *count_override = replacement + expected_count = count_override[0] if count_override else 1 + replacement_count = count_override[1] if len(count_override) > 1 else expected_count + testcase.assertEqual(original.count(source), expected_count, source) + original = original.replace(source, target, replacement_count) testcase.assertEqual( (FRONTEND_ROOT / target_relative).read_text(encoding="utf-8"), original, diff --git a/docs/governance/code-reduction.md b/docs/governance/code-reduction.md index 3d72ce0..64880dd 100644 --- a/docs/governance/code-reduction.md +++ b/docs/governance/code-reduction.md @@ -348,6 +348,21 @@ 本批基线为`xiaobai-reduction-12-css-exact-duplicates-20260802`;检查点为 `xiaobai-reduction-13-css-nested-duplicates-20260802`。 +## CR-13后续产品修正:龙虎榜整页滚动 + +- 2026-08-02用户明确要求取消龙虎榜“当日操作明细单独纵向滚动”,改为龙虎榜主内容区整页纵向滚动, + 解决低分辨率下操作明细可视高度过小的问题;这是经批准的产品行为变化,不作为CSS去重处理。 +- 龙虎榜从桌面固定视口共享规则中独立出来;主内容区继续使用工作区高度并承担纵向滚动,游资卡片、 + 操作明细和待归类席位按内容自然展开,宽操作表继续保留横向滚动。 +- 保真门禁以精确源码替换单独登记本次差异,其他CSS仍与原母版逐字符比较;未新增覆盖层或第二套规则。 +- 1366×768真实页面中主内容区为692px、内容高度为2620px,整页滚动可达;操作明细自身高度与内容 + 高度一致,不再形成纵向小窗口,1180px宽表仍可横向滚动。 +- 本次不修改龙虎榜数据、筛选、搜索、游资卡牌、表格字段、游资档案、API、数据库或其他页面的 + 滚动所有权。 + +本修正基线为`xiaobai-reduction-13-css-nested-duplicates-20260802`;检查点为 +`xiaobai-fix-dragon-page-scroll-20260802`。 + ## 人工验收记录 - 2026-08-01:用户检查CR-02与CR-03运行结果,确认未发现明显异常。本记录仅表示本轮可见功能与