fix(viewer): compact left panel typography and layout so it fits without scrolling
- Panel text reduced to 14px (headings, labels, buttons) and 13px (notes, specs). - Hint notes removed; part selection moved into a closed disclosure (summary shows selected part). - Pattern list in four columns; section rhythm tightened. - At 1440x900 and 1920x1080 the panel fits without scrolling. Below ~830px height it still scrolls. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A5Cun3RHQKna9qxE6ybZ4A
This commit is contained in:
1 parent
e254718309
commit
7e4c79c86d
1 file changed
+47
-29
+47
-29
@@ -102,7 +102,7 @@ body {
|
||||
}
|
||||
h1, h2, p, dl, dd, dt { margin: 0; }
|
||||
h1 { font-size: var(--prism-type-title-sm); line-height: var(--prism-lh-title); font-weight: 700; color: var(--prism-text-heading); }
|
||||
h2 { font-size: var(--prism-type-body-lg); line-height: var(--prism-lh-title); font-weight: 700; color: var(--prism-text-heading); margin-block: var(--prism-space-300) var(--prism-space-100); }
|
||||
h2 { font-size: var(--prism-type-body-sm); line-height: var(--prism-lh-title); font-weight: 700; color: var(--prism-text-heading); margin-block: var(--prism-space-150) var(--prism-space-050); }
|
||||
.rail h2:first-child { margin-block-start: 0; }
|
||||
|
||||
/* 포커스: 3px 링 + 오프셋 2px, :focus-visible 전용 (FC-1·FC-2) */
|
||||
@@ -139,7 +139,7 @@ h2 { font-size: var(--prism-type-body-lg); line-height: var(--prism-lh-title); f
|
||||
/* 셸: 좌측 내비 레일 + 뷰포트 (W1) */
|
||||
.shell { flex: 1; min-height: 0; display: grid; grid-template-columns: 17.5rem minmax(0, 1fr); }
|
||||
.rail {
|
||||
overflow: auto; padding: var(--prism-space-200);
|
||||
overflow: auto; padding: var(--prism-space-150);
|
||||
background: var(--prism-bg-card); border-inline-end: var(--prism-stroke-hairline) solid var(--prism-border-default);
|
||||
}
|
||||
.stage { position: relative; min-width: 0; min-height: 0; }
|
||||
@@ -148,7 +148,7 @@ h2 { font-size: var(--prism-type-body-lg); line-height: var(--prism-lh-title); f
|
||||
|
||||
/* 버튼 — primary 화면당 1개 (BT-1), 히트 영역 44px (HT-1) */
|
||||
button {
|
||||
font: inherit; font-size: var(--prism-type-body); font-weight: 500; line-height: 1.2;
|
||||
font: inherit; font-size: var(--prism-type-body-sm); font-weight: 500; line-height: 1.2;
|
||||
min-height: 2.75rem; padding: var(--prism-space-050) var(--prism-space-100); white-space: nowrap;
|
||||
border: var(--prism-stroke-hairline) solid var(--prism-border-default); border-radius: var(--prism-radius-md);
|
||||
background: var(--prism-bg-card); color: var(--prism-text-body); cursor: pointer;
|
||||
@@ -161,10 +161,11 @@ button.quiet { background: transparent; border-color: transparent; color: var(--
|
||||
/* 체크박스 행 — 히트 영역 44px */
|
||||
.opt {
|
||||
display: flex; align-items: center; gap: var(--prism-space-100);
|
||||
min-height: 2.75rem; cursor: pointer; color: var(--prism-text-body);
|
||||
min-height: 2.75rem; cursor: pointer; color: var(--prism-text-body); font-size: var(--prism-type-body-sm);
|
||||
}
|
||||
.opt input[type="checkbox"] { width: 1.25rem; height: 1.25rem; margin: 0; flex: none; accent-color: var(--prism-text-heading); }
|
||||
.pats { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--prism-space-100); }
|
||||
.pats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--prism-space-050); }
|
||||
.pats .opt { gap: var(--prism-space-050); white-space: nowrap; }
|
||||
.sw {
|
||||
width: var(--prism-space-200); height: var(--prism-space-200); flex: none;
|
||||
border-radius: var(--prism-radius-sm); border: var(--prism-stroke-hairline) solid var(--prism-border-default);
|
||||
@@ -192,23 +193,37 @@ button.quiet { background: transparent; border-color: transparent; color: var(--
|
||||
pointer-events: auto; cursor: pointer; width: 1.25rem; height: 1.25rem; border-radius: 50%;
|
||||
background: var(--prism-text-heading); border: var(--prism-stroke-regular) solid var(--prism-bg-card);
|
||||
}
|
||||
.sta { font-weight: 700; font-variant-numeric: tabular-nums; margin-block: var(--prism-space-050) var(--prism-space-100); }
|
||||
.sta { font-size: var(--prism-type-body-sm); font-weight: 700; font-variant-numeric: tabular-nums; margin-block: var(--prism-space-050) var(--prism-space-100); }
|
||||
|
||||
|
||||
/* 개폐 (component.disclosure) — 부품 선택은 기본 접힘 */
|
||||
.disc { margin-block-start: var(--prism-space-150); border-top: var(--prism-stroke-hairline) solid var(--prism-border-default); padding-block-start: var(--prism-space-050); }
|
||||
.disc > summary {
|
||||
display: flex; align-items: center; justify-content: space-between; gap: var(--prism-space-100);
|
||||
min-height: 2.75rem; cursor: pointer; list-style: none; font-size: var(--prism-type-body-sm); font-weight: 700; color: var(--prism-text-heading);
|
||||
}
|
||||
.disc > summary::-webkit-details-marker { display: none; }
|
||||
.disc > summary > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
|
||||
.disc > summary::after { content: "+"; flex: none; font-weight: 500; color: var(--prism-text-subtle); }
|
||||
.disc[open] > summary::after { content: "−"; }
|
||||
.disc > summary:focus-visible { outline: var(--prism-focus-ring) solid var(--prism-text-heading); outline-offset: var(--prism-focus-offset); }
|
||||
.disc > *:not(summary) { margin-block-start: var(--prism-space-100); }
|
||||
|
||||
/* 선택 목록 */
|
||||
select {
|
||||
font: inherit; font-size: var(--prism-type-body); width: 100%; min-height: 2.75rem;
|
||||
font: inherit; font-size: var(--prism-type-body-sm); width: 100%; min-height: 2.75rem;
|
||||
padding: var(--prism-space-050) var(--prism-space-100); border-radius: var(--prism-radius-md);
|
||||
border: var(--prism-stroke-hairline) solid var(--prism-border-default);
|
||||
background: var(--prism-bg-card); color: var(--prism-text-body);
|
||||
}
|
||||
.label { display: block; margin-block-end: var(--prism-space-050); color: var(--prism-text-subtle); font-size: var(--prism-type-caption); line-height: var(--prism-lh-caption); }
|
||||
.note { color: var(--prism-text-subtle); font-size: var(--prism-type-caption); line-height: var(--prism-lh-caption); max-inline-size: var(--prism-measure-max); margin-block-start: var(--prism-space-100); }
|
||||
.empty { color: var(--prism-text-subtle); font-size: var(--prism-type-body-sm); margin-block-start: var(--prism-space-100); }
|
||||
.empty { color: var(--prism-text-subtle); font-size: var(--prism-type-caption); margin-block-start: var(--prism-space-100); }
|
||||
|
||||
/* 명세표 (specsheet) — 항목 말미 고정 위치, 열 구성 동일 (SS-1·SS-2) */
|
||||
.spec {
|
||||
display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--prism-space-050) var(--prism-space-150);
|
||||
font-size: var(--prism-type-body-sm); line-height: var(--prism-lh-body); font-variant-numeric: tabular-nums;
|
||||
font-size: var(--prism-type-caption); line-height: var(--prism-lh-caption); font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.spec dt { color: var(--prism-text-subtle); }
|
||||
.spec dd { overflow-wrap: anywhere; color: var(--prism-text-body); }
|
||||
@@ -270,8 +285,7 @@ select {
|
||||
|
||||
<div class="shell">
|
||||
<nav class="rail" aria-label="모델 제어">
|
||||
<h2>시점</h2>
|
||||
<div class="btn-grid">
|
||||
<div class="btn-grid" role="group" aria-label="시점">
|
||||
<button type="button" class="primary" id="btnStart">종단 보기</button>
|
||||
<button type="button" id="btnAll">전체 맞추기</button>
|
||||
</div>
|
||||
@@ -287,31 +301,29 @@ select {
|
||||
<button type="button" id="btnWin">구간 맞추기</button>
|
||||
<button type="button" id="btnWinReset" class="quiet">구간 전체</button>
|
||||
</div>
|
||||
<p class="note">슬라이더는 5 m 단위로 움직입니다.</p>
|
||||
|
||||
<h2>지보패턴</h2>
|
||||
<div class="pats" id="pats"></div>
|
||||
<p class="note">라이닝과 굴착 여유대를 패턴별로 켜고 끕니다.</p>
|
||||
|
||||
<h2>구성요소</h2>
|
||||
<div id="comps"></div>
|
||||
|
||||
<h2>부품 선택</h2>
|
||||
<label class="label" for="pickSel">목록에서 부품 고르기</label>
|
||||
<select id="pickSel">
|
||||
<option value="">선택 없음</option>
|
||||
</select>
|
||||
<dl class="spec" id="detailSpec" hidden style="margin-block-start:var(--prism-space-150)"></dl>
|
||||
<p class="empty" id="detailEmpty">부품을 클릭하거나 목록에서 고르면 속성이 표시됩니다.</p>
|
||||
<div class="btn-grid" style="margin-block-start:var(--prism-space-150)">
|
||||
<button type="button" id="btnFitSel">선택 맞추기</button>
|
||||
<button type="button" id="btnDesel" class="quiet">선택 해제</button>
|
||||
<button type="button" id="btnHideSel">선택 숨기기</button>
|
||||
<button type="button" id="btnIsoSel">선택만 보기</button>
|
||||
<button type="button" id="btnShowAll" class="quiet wide">모두 보기</button>
|
||||
</div>
|
||||
<label class="opt" style="margin-block-start:var(--prism-space-150)"><input type="checkbox" id="wire"> 와이어프레임으로 보기</label>
|
||||
<p class="note">드래그 회전 · 휠 확대 · 클릭 선택 · Esc 선택 해제</p>
|
||||
<details class="disc" id="partDisc">
|
||||
<summary><span id="partSummary">부품 선택</span></summary>
|
||||
<select id="pickSel" aria-label="부품 목록에서 고르기">
|
||||
<option value="">선택 없음</option>
|
||||
</select>
|
||||
<dl class="spec" id="detailSpec" hidden></dl>
|
||||
<p class="empty" id="detailEmpty">부품을 클릭하거나 목록에서 고르면 속성이 표시됩니다.</p>
|
||||
<div class="btn-grid" style="margin-block-start:var(--prism-space-100)">
|
||||
<button type="button" id="btnFitSel">선택 맞추기</button>
|
||||
<button type="button" id="btnDesel" class="quiet">선택 해제</button>
|
||||
<button type="button" id="btnHideSel">선택 숨기기</button>
|
||||
<button type="button" id="btnIsoSel">선택만 보기</button>
|
||||
<button type="button" id="btnShowAll" class="quiet wide">모두 보기</button>
|
||||
</div>
|
||||
<label class="opt" style="margin-block-start:var(--prism-space-050)"><input type="checkbox" id="wire"> 와이어프레임으로 보기</label>
|
||||
</details>
|
||||
</nav>
|
||||
|
||||
<main id="main" class="stage">
|
||||
@@ -467,6 +479,11 @@ function startView() {
|
||||
controls.update();
|
||||
}
|
||||
|
||||
// 부품 선택 개폐 상태 저장 (DC-3)
|
||||
const DISC_KEY = 'prism-viewer-part-open';
|
||||
try { $('partDisc').open = localStorage.getItem(DISC_KEY) === '1'; } catch (e) { /* 무시 */ }
|
||||
$('partDisc').addEventListener('toggle', () => { try { localStorage.setItem(DISC_KEY, $('partDisc').open ? '1' : '0'); } catch (e) { /* 무시 */ } });
|
||||
|
||||
// ── 부품 상세 (명세표) ──
|
||||
function specRows(u) {
|
||||
return [
|
||||
@@ -497,6 +514,7 @@ function setSelected(m) {
|
||||
selected = m;
|
||||
if (m) m.material.emissive.set(tok('--prism-text-heading'));
|
||||
$('pickSel').value = m ? String(m.userData.idx) : '';
|
||||
$('partSummary').textContent = m ? '부품 선택 · ' + m.userData.id : '부품 선택 · 선택 없음';
|
||||
applyVisibility();
|
||||
renderDetail(m ? m.userData : null);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user