diff --git a/src/features/tech-log/presentation/styles/globals.css b/src/features/tech-log/presentation/styles/globals.css index a86a5a1..aa1885a 100644 --- a/src/features/tech-log/presentation/styles/globals.css +++ b/src/features/tech-log/presentation/styles/globals.css @@ -795,14 +795,14 @@ a { } .code-block { - width: min(58rem, calc(100% + 12rem)); - margin: 38px 0 39px 50%; + width: min(var(--body-copy), 100%); + margin: 38px auto 39px; overflow: hidden; border: 1px solid #242831; border-radius: 8px; background: var(--code-canvas); color: #e8ebf2; - transform: translateX(-50%); + transform: none; } .code-block figcaption { @@ -872,12 +872,12 @@ a { } .data-table-wrap { - width: min(58rem, calc(100% + 12rem)); - margin: 37px 0 40px 50%; + width: min(var(--body-copy), 100%); + margin: 37px auto 40px; overflow-x: auto; border-top: 1px solid var(--line-strong); border-bottom: 1px solid var(--line-strong); - transform: translateX(-50%); + transform: none; } .data-table-wrap table { @@ -961,9 +961,9 @@ a { } .evidence-figure { - width: min(61rem, calc(100% + 15rem)); - margin: 43px 0 42px 50%; - transform: translateX(-50%); + width: min(var(--body-copy), 100%); + margin: 43px auto 42px; + transform: none; } .evidence-image-button { @@ -1429,19 +1429,6 @@ dialog::backdrop { display: none; } - .code-block, - .data-table-wrap { - width: min(58rem, calc(100vw - 64px)); - margin-left: 50%; - transform: translateX(-50%); - } - - .evidence-figure { - width: min(61rem, calc(100vw - 64px)); - margin-left: 50%; - transform: translateX(-50%); - } - .mobile-toc-wrap { display: block; margin-bottom: 62px; diff --git a/tests/features/tech-log/style-contract.test.ts b/tests/features/tech-log/style-contract.test.ts index a076c7b..6ad287a 100644 --- a/tests/features/tech-log/style-contract.test.ts +++ b/tests/features/tech-log/style-contract.test.ts @@ -96,6 +96,59 @@ describe("TechLog consumer-visible style contract", () => { expect(getComputedStyle(wordmark).fontWeight).toBe("680"); }); + it("aligns code, table, and evidence widths with the article body", () => { + const view = renderPublicSurface( + createElement( + "main", + { id: "main-content", className: "shell" }, + createElement( + "article", + { className: "document-body" }, + createElement( + "section", + null, + createElement("p", null, "본문"), + createElement( + "figure", + { className: "code-block" }, + createElement("pre", null, createElement("code", null, "code")), + ), + createElement( + "div", + { className: "data-table-wrap" }, + createElement("table", null, createElement("tbody")), + ), + createElement( + "figure", + { className: "evidence-figure" }, + createElement("img", { alt: "근거 자료" }), + ), + ), + ), + ), + ); + + const article = view.container.querySelector(".document-body"); + const code = view.container.querySelector(".code-block"); + const codeScroller = view.container.querySelector( + ".code-block pre", + ); + const table = view.container.querySelector(".data-table-wrap"); + const evidence = view.container.querySelector( + ".evidence-figure", + ); + + expect(getComputedStyle(article!).width).toBe("min(100%, var(--body-copy))"); + for (const material of [code, table, evidence]) { + expect(getComputedStyle(material!).width).toBe( + "min(var(--body-copy), 100%)", + ); + expect(getComputedStyle(material!).transform).toBe("none"); + } + expect(getComputedStyle(codeScroller!).overflowX).toBe("auto"); + expect(getComputedStyle(table!).overflowX).toBe("auto"); + }); + it("preserves keyboard focus and the real search-field focus style", async () => { const user = userEvent.setup(); const view = renderPublicSurface(