@import "tailwindcss"; /* 색 토큰의 정의처는 앱과 같은 파일 하나 — 여기서 색을 새로 정하지 않는다. */ @import "../../../ui_template/ui_template_theme.css"; :root { --cad-title-height: 42px; /* 116px 에서는 리본 줄의 내용(85px)이 보이는 높이(81px)를 넘어 세로 스크롤바가 생겼다(2026-09-04 실측) — 모자란 4px + 여유 2px 를 더한다. */ --cad-ribbon-height: 122px; /* 명령행 높이 — 상태막대의 [명령행] 토글이 0px로 바꾼다 */ --cad-command-height: 86px; --cad-status-height: 28px; /* 도면층 한 행에 아이콘 6개와 이름이 함께 들어가는 폭. 248px에서는 이름 몫이 21px밖에 남지 않아 글자가 뭉개졌다(2026-09-01 실측). */ --cad-panel-width: 300px; font-family: var(--font-body); color: var(--color-text-body); background: var(--color-bg); /* CAD 표면 단계 — 앱 토큰을 CAD 골격(툴바·리본·패널)에 이름만 붙여 쓴다. */ --cad-chrome: var(--color-surface); --cad-chrome-raised: var(--color-surface-raised); --cad-chrome-sunken: var(--color-bg); --cad-line: var(--color-border); --cad-text: var(--color-text-body); --cad-text-dim: var(--color-text-secondary); --cad-text-muted: var(--color-text-muted); --cad-accent: var(--color-accent); --cad-hover: var(--color-mist-violet); --cad-canvas: var(--color-canvas); } * { box-sizing: border-box; } html, body, #root { width: 100%; height: 100%; margin: 0; overflow: hidden; } button, input { font: inherit; } button { color: inherit; } .cad-app { position: fixed; inset: 0; z-index: 2; pointer-events: none; } .controls { pointer-events: auto; } body > canvas[data-id="canvas"] { position: fixed; z-index: 1; top: calc(var(--cad-title-height) + var(--cad-ribbon-height)); right: 0; bottom: calc(var(--cad-command-height) + var(--cad-status-height)); left: var(--cad-panel-width); width: calc(100vw - var(--cad-panel-width)); height: calc( 100vh - var(--cad-title-height) - var(--cad-ribbon-height) - var(--cad-command-height) - var(--cad-status-height) ); background: var(--cad-canvas); cursor: none; } .cad-titlebar { position: fixed; inset: 0 0 auto 0; height: var(--cad-title-height); display: flex; align-items: center; gap: 24px; padding: 0 12px; background: var(--cad-chrome); border-bottom: 1px solid var(--cad-line); box-shadow: var(--shadow-sm); } .cad-brand { display: flex; align-items: baseline; gap: 9px; min-width: 220px; } .cad-brand strong { color: var(--color-text); font-size: 14px; } .cad-brand span, .cad-file-state { color: var(--cad-text-dim); font-size: 11px; } .cad-file-state { display: flex; align-items: center; gap: 7px; } .cad-file-state__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--color-success); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-success) 25%, transparent); } .cad-title-actions { display: flex; gap: 4px; margin-left: auto; } .cad-title-actions button { height: 28px; min-width: 32px; padding: 0 9px; border: 1px solid transparent; border-radius: 3px; background: transparent; font-size: 12px; } .cad-title-actions button:hover { border-color: var(--cad-line); background: var(--cad-hover); } .cad-ribbon { position: fixed; top: var(--cad-title-height); right: 0; left: 0; height: var(--cad-ribbon-height); display: flex; flex-direction: column; background: var(--cad-chrome-raised); border-bottom: 1px solid var(--cad-line); } .cad-ribbon-tabs { display: flex; gap: 2px; height: 26px; padding: 0 8px; border-bottom: 1px solid var(--cad-line); } .cad-ribbon-tabs button { padding: 0 14px; border: 1px solid transparent; border-bottom: 0; border-radius: 4px 4px 0 0; background: transparent; color: var(--cad-text-dim); font-size: 12px; } .cad-ribbon-tabs button:hover { background: var(--cad-hover); } .cad-ribbon-tabs button[data-active="true"] { background: var(--cad-chrome); border-color: var(--cad-line); color: var(--color-text); } .cad-ribbon-panels { display: flex; flex: 1; align-items: stretch; padding: 4px 8px 2px; overflow-x: auto; overflow-y: visible; } .cad-ribbon-group { position: relative; display: flex; flex-direction: column; min-width: max-content; padding: 0 9px; border-right: 1px solid var(--cad-line); } .cad-ribbon-tools { display: flex; gap: 3px; align-items: flex-start; height: 66px; } .cad-ribbon-tools__grid { display: grid; grid-template-rows: 1fr 1fr; grid-auto-flow: column; gap: 1px; } .cad-ribbon-group__label { margin-top: auto; padding: 0; border: 0; background: transparent; color: var(--cad-text-muted); font-size: 10px; text-align: center; } .cad-ribbon-group__label[data-expandable="true"] { cursor: pointer; } .cad-ribbon-group__label[data-expandable="true"]:hover { color: var(--cad-accent); } .cad-ribbon-overflow { /* 리본 패널 줄이 가로 스크롤 상자라 그 안에서는 잘린다 — 화면 좌표로 띄운다 */ position: fixed; z-index: 20; display: flex; flex-direction: column; min-width: 170px; max-height: 72vh; padding: 4px; overflow-y: auto; background: var(--cad-chrome-raised); border: 1px solid var(--cad-line); border-radius: 4px; box-shadow: var(--shadow-lg); } .cad-ribbon-overflow button { display: flex; gap: 8px; align-items: center; padding: 5px 8px; border: 0; border-radius: 3px; background: transparent; font-size: 11px; text-align: left; } .cad-ribbon-overflow button:hover { background: var(--cad-hover); } .cad-quick-access { display: flex; gap: 2px; margin-left: 14px; } .cad-quick-access button { width: 26px; height: 24px; border: 1px solid transparent; border-radius: 3px; background: transparent; font-size: 13px; } .cad-quick-access button:hover { border-color: var(--cad-line); background: var(--cad-hover); } .cad-ribbon-props { display: flex; flex-direction: column; gap: 3px; align-items: stretch; justify-content: flex-start; } /* 위젯 패널은 한 줄에 라벨+입력을 놓고 세로로 쌓는다 (리본 높이 안에 들어가야 한다) */ .cad-prop { display: flex; flex-direction: row; gap: 6px; align-items: center; font-size: 10px; color: var(--cad-text-muted); } .cad-prop > span { width: 52px; text-align: left; } .cad-prop select, .cad-prop input[type="number"] { height: 19px; min-width: 78px; padding: 0 3px; color: var(--cad-text); background: var(--cad-chrome-sunken); border: 1px solid var(--cad-line); border-radius: 3px; font-size: 11px; } .cad-prop input[type="number"] { min-width: 52px; width: 52px; } .cad-prop input[type="color"] { height: 19px; width: 44px; padding: 1px; background: var(--cad-chrome-sunken); /* 흰색을 골라도 스와치 자리가 보이게 테두리를 진하게 준다 (2026-09-01) */ border: 1px solid var(--cad-text-muted); border-radius: 3px; cursor: pointer; } /* 위젯 패널 안의 작은 명령 버튼은 한 줄 높이에 맞춘다 */ .cad-ribbon-props .cad-tool[data-size="small"] { height: 22px; min-width: 0; } .cad-tool { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 48px; padding: 3px 6px; border: 1px solid transparent; border-radius: 3px; background: transparent; font-size: 10px; white-space: nowrap; } .cad-tool[data-size="big"] { min-width: 58px; height: 66px; } .cad-tool[data-size="big"] .cad-tool__glyph { height: 32px; font-size: 26px; line-height: 32px; } .cad-tool[data-size="small"] { flex-direction: row; justify-content: flex-start; gap: 4px; min-width: 78px; height: 32px; padding: 0 5px; } .cad-tool[data-size="small"] .cad-tool__glyph { height: auto; font-size: 15px; line-height: 1; } .cad-tool:hover:not(:disabled), .cad-tool[data-active="true"] { border-color: var(--cad-accent); background: var(--cad-hover); } .cad-tool[data-active="true"] { box-shadow: inset 0 -2px var(--cad-accent); } .cad-tool:disabled { color: var(--color-smoke); cursor: not-allowed; } .cad-tool__glyph { height: 27px; color: var(--cad-accent); font-size: 22px; line-height: 27px; } .cad-tool:disabled .cad-tool__glyph { color: var(--color-smoke); } .cad-inspector { position: fixed; z-index: 3; top: calc(var(--cad-title-height) + var(--cad-ribbon-height)); /* 좌측 팔레트가 상위 — 명령행 토글에 높이가 흔들리지 않게 상태막대까지 내린다 */ bottom: var(--cad-status-height); left: 0; width: var(--cad-panel-width); background: var(--cad-chrome); border-right: 1px solid var(--cad-line); transition: width 120ms ease; } .cad-inspector[data-collapsed="true"] { width: 0; } .cad-inspector__collapse { position: absolute; z-index: 4; top: 10px; left: 100%; width: 20px; height: 38px; border: 1px solid var(--cad-line); border-left: 0; border-radius: 0 4px 4px 0; background: var(--cad-chrome-raised); color: var(--cad-text-dim); } .cad-inspector-tabs { display: grid; grid-template-columns: 1fr 1fr; height: 38px; border-bottom: 1px solid var(--cad-line); } .cad-inspector-tabs button { border: 0; border-bottom: 2px solid transparent; background: var(--cad-chrome-sunken); color: var(--cad-text-dim); font-size: 12px; } .cad-inspector-tabs button[data-active="true"] { border-bottom-color: var(--cad-accent); background: var(--cad-chrome-raised); color: var(--color-text); } .cad-properties { padding: 14px 12px; } .cad-properties h2 { margin: 0 0 14px; color: var(--color-text); font-size: 13px; font-weight: 600; } .cad-properties dl { margin: 0; border-top: 1px solid var(--cad-line); } .cad-properties dl div { display: grid; grid-template-columns: 92px 1fr; padding: 8px 0; border-bottom: 1px solid var(--cad-line); font-size: 11px; } .cad-properties dt { color: var(--cad-text-dim); } .cad-properties dd { margin: 0; overflow: hidden; color: var(--cad-text); text-overflow: ellipsis; } .cad-layer-manager { max-height: calc(100vh - 250px); padding: 9px; overflow-y: auto; overflow-x: hidden; } .cad-layer-manager button { min-height: 36px; padding-top: 6px; padding-bottom: 6px; } /* 도면층 행: 이름은 줄여 담고 아이콘은 줄이지 않는다. 이름이 안 줄면 오른쪽 아이콘이 행 밖으로 밀려 잘린다 (2026-09-01 실측: 내용 237~286px / 보이는 폭 229px). */ .cad-layer-manager .layer > button > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .cad-layer-manager .layer > button > div { flex-shrink: 0; } /* 행 안의 아이콘 버튼은 여백을 줄여 이름 몫을 남긴다 — 아이콘 6개가 한 행을 다 먹었다. */ .cad-layer-manager .layer > button [data-size="small"] { padding-left: 2px; padding-right: 2px; min-width: 0; } /* 도면층 버튼 — 색은 토큰으로만, 상태는 Button이 붙이는 data-* 속성으로 가른다. */ .cad-layer-manager button[data-type="regular"] { background: var(--cad-chrome-sunken); color: var(--cad-accent); } .cad-layer-manager button[data-type="transparent"] { background: transparent; color: var(--cad-accent); } .cad-layer-manager button:hover { background: var(--cad-hover); color: var(--color-text); } .cad-layer-manager button[data-active="true"] { background: var(--color-primary); color: var(--color-primary-text); } .cad-view-controls { position: fixed; z-index: 3; right: 14px; bottom: calc(var(--cad-command-height) + var(--cad-status-height) + 14px); display: flex; align-items: center; overflow: hidden; border: 1px solid var(--cad-line); border-radius: 4px; background: var(--cad-chrome-raised); box-shadow: var(--shadow-lg); } .cad-view-controls button { width: 34px; height: 32px; border: 0; border-right: 1px solid var(--cad-line); background: transparent; font-size: 17px; } .cad-view-controls button:hover { background: var(--cad-hover); } .cad-view-controls__fit { color: var(--cad-accent); font-size: 15px; } .cad-view-controls span { min-width: 48px; color: var(--cad-text-dim); font-size: 10px; text-align: center; } /* 하단 명령어 입력창은 숨김 처리 (마우스 커서 단축키 입력으로 대체) */ .cad-command-area { position: fixed; z-index: 3; right: 0; bottom: var(--cad-status-height); left: var(--cad-panel-width); height: var(--cad-command-height); display: flex; flex-direction: column; gap: 4px; padding: 6px 10px; background: var(--cad-chrome); border-top: 1px solid var(--cad-line); } .cad-command-history { display: flex; flex-direction: column; flex: 1; justify-content: flex-end; overflow: hidden; color: var(--cad-text-muted); font: 11px Consolas, monospace; } .cad-command-suggestions { position: absolute; z-index: 6; bottom: 100%; left: 10px; display: flex; flex-direction: column; min-width: 220px; padding: 4px; background: var(--cad-chrome-raised); border: 1px solid var(--cad-line); border-radius: 4px; box-shadow: var(--shadow-lg); } .cad-command-suggestions button { padding: 4px 8px; border: 0; border-radius: 3px; background: transparent; font: 11px Consolas, monospace; text-align: left; } .cad-command-suggestions button:hover { background: var(--cad-hover); } .cad-prop--wide select { min-width: 132px; } .cad-command-prompt { max-width: 42%; overflow: hidden; color: var(--cad-text-dim); font-size: 11px; white-space: nowrap; text-overflow: ellipsis; } .cad-command-area form { display: flex; align-items: center; gap: 7px; height: 28px; } .cad-command-area label { color: var(--color-text); font-size: 11px; font-weight: 600; } .cad-command-area input { flex: 1; height: 26px; padding: 0 8px; border: 1px solid var(--cad-line); border-radius: 2px; outline: none; background: var(--cad-chrome-sunken); color: var(--cad-text); font: 11px Consolas, monospace; } .cad-command-area input:focus { border-color: var(--color-focus-ring); box-shadow: 0 0 0 1px var(--color-focus-ring); } .cad-statusbar { position: fixed; z-index: 3; right: 0; bottom: 0; left: 0; height: var(--cad-status-height); display: flex; align-items: center; gap: 2px; padding: 0 8px; background: var(--cad-chrome); border-top: 1px solid var(--cad-line); } .cad-statusbar button { height: 21px; padding: 0 8px; border: 1px solid transparent; border-radius: 2px; background: transparent; color: var(--cad-text-dim); font-size: 10px; } .cad-statusbar button:hover { background: var(--cad-hover); } .cad-statusbar button[data-active="true"] { border-color: var(--cad-accent); background: var(--color-primary); color: var(--color-primary-text); } .cad-statusbar__hint { margin-left: auto; color: var(--cad-text-muted); font-size: 10px; } /* ----------------------------------------------------------------------------- * 수량 산출표 패널 (CAD 화면 하단 중심, 접이식) — 첨부 양식 * -------------------------------------------------------------------------- */ .cad-qtable { position: fixed; z-index: 3; /* 명령행 위로 띄운다 — 겹치면 명령 입력칸을 클릭으로 누를 수 없다(2026-08-31). 명령행을 접으면 --cad-command-height가 0이라 예전처럼 상태막대 위에 붙는다. */ bottom: calc(var(--cad-status-height) + var(--cad-command-height) + 8px); left: calc(var(--cad-panel-width) + (100vw - var(--cad-panel-width)) / 2); transform: translateX(-50%); /* 표(가장 넓은 자식) 기준 폭 고정 → 접었다 펴도 폭이 변하지 않는다 */ width: max-content; max-width: min(1040px, calc(100vw - var(--cad-panel-width) - 24px)); border: 1px solid var(--cad-line); border-radius: 6px; background: var(--cad-chrome-raised); box-shadow: var(--shadow-lg); color: var(--cad-text); } .cad-qtable__header { display: flex; align-items: center; gap: 8px; padding: 5px 8px; } .cad-qtable__title { display: flex; flex: 1; align-items: baseline; justify-content: center; gap: 8px; min-width: 0; } .cad-qtable__title strong { color: var(--color-text); font-size: 14px; } .cad-qtable__title span { overflow: hidden; color: var(--cad-text-dim); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; } .cad-qtable__status { padding: 1px 7px; border-radius: 999px; font-size: 10px; font-style: normal; } .cad-qtable__status[data-confirmed="true"] { background: color-mix(in srgb, var(--color-success) 22%, transparent); color: var(--color-success); } .cad-qtable__status[data-confirmed="false"] { background: color-mix(in srgb, var(--color-warning) 22%, transparent); color: var(--color-warning); } .cad-qtable__nav, .cad-qtable__collapse { width: 26px; height: 24px; border: 1px solid var(--cad-line); border-radius: 4px; background: var(--cad-chrome-sunken); color: var(--cad-text); font-size: 13px; } .cad-qtable__nav:hover:not(:disabled), .cad-qtable__collapse:hover { background: var(--cad-hover); } .cad-qtable__nav:disabled { opacity: 0.35; cursor: not-allowed; } .cad-qtable__body { padding: 0 8px 8px; overflow-x: auto; } /* 접힘: 표는 DOM에 남겨 폭은 유지하되 세로로만 감춘다 */ .cad-qtable[data-collapsed="true"] .cad-qtable__body { max-height: 0; padding-top: 0; padding-bottom: 0; overflow: hidden; visibility: hidden; } .cad-qtable table { margin: 0 auto; border-collapse: collapse; } .cad-qtable th, .cad-qtable td { padding: 0; border: 1px solid var(--cad-line); font-size: 11px; text-align: center; vertical-align: middle; } .cad-qtable__label { padding: 2px 9px; color: var(--cad-text-dim); font-weight: 600; white-space: nowrap; background: var(--cad-chrome); } .cad-qtable__label--vertical { width: 18px; writing-mode: vertical-rl; text-orientation: upright; letter-spacing: 1px; } .cad-qtable__value input { width: 72px; padding: 3px 4px; border: 0; background: transparent; color: var(--cad-text); font: inherit; text-align: center; } .cad-qtable__value input:focus { outline: 2px solid var(--color-focus-ring); outline-offset: -2px; background: var(--cad-hover); } .cad-qtable__value--derived input { color: var(--cad-text-muted); background: var(--cad-chrome-sunken); cursor: not-allowed; } @media (max-width: 800px) { :root { --cad-panel-width: 200px; } .cad-file-state, .cad-statusbar__hint { display: none; } .cad-brand { min-width: auto; } } /* 특성 팔레트 — 값을 바로 고치는 입력들 */ .cad-properties-editor { display: flex; flex-direction: column; gap: 7px; } .cad-properties-editor__title { color: var(--color-text); font-size: 13px; font-weight: 600; } .cad-properties-editor label { display: grid; grid-template-columns: 72px 1fr; align-items: center; gap: 8px; font-size: 11px; color: var(--cad-text-dim); } .cad-properties-editor select, .cad-properties-editor input { height: 24px; min-width: 0; padding: 0 4px; border: 1px solid var(--cad-line); border-radius: 3px; background: var(--cad-chrome-sunken); color: var(--cad-text); font-size: 11px; } .cad-properties-editor__readout { margin: 6px 0 0; border-top: 1px solid var(--cad-line); } .cad-properties-editor__readout div { display: grid; grid-template-columns: 72px 1fr; padding: 5px 0; border-bottom: 1px solid var(--cad-line); font-size: 11px; } .cad-properties-editor__readout dt { color: var(--cad-text-dim); } .cad-properties-editor__readout dd { margin: 0; overflow: hidden; color: var(--cad-text); text-overflow: ellipsis; } .cad-properties__empty { margin: 0; color: var(--cad-text-muted); font-size: 11px; } /* 빠른 특성 — 화면 위에 뜨는 작은 상자 */ .cad-quick-properties { position: fixed; z-index: 5; top: calc(var(--cad-title-height) + var(--cad-ribbon-height) + 12px); right: 14px; width: 240px; padding: 8px 10px 10px; background: var(--cad-chrome-raised); border: 1px solid var(--cad-line); border-radius: 5px; box-shadow: var(--shadow-lg); } .cad-quick-properties__header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; color: var(--cad-text-dim); font-size: 11px; } .cad-quick-properties__header button { border: 0; background: transparent; color: var(--cad-text-muted); font-size: 12px; } /* 블록 라이브러리 팔레트 (INSERT/BLOCK) */ .cad-block-library { position: fixed; z-index: 5; top: calc(var(--cad-title-height) + var(--cad-ribbon-height) + 12px); right: 14px; width: 240px; padding: 8px 10px 10px; background: var(--cad-chrome-raised); border: 1px solid var(--cad-line); border-radius: 5px; box-shadow: var(--shadow-lg); } .cad-block-library__empty { margin: 0; color: var(--cad-text-muted); font-size: 11px; line-height: 1.5; } .cad-block-library__list { max-height: 220px; margin: 0; padding: 0; overflow-y: auto; list-style: none; } .cad-block-library__list li { display: flex; align-items: center; gap: 4px; } .cad-block-library__list li button { border: 0; background: transparent; color: var(--cad-text); font-size: 12px; } .cad-block-library__name { flex: 1; overflow: hidden; padding: 3px 4px; text-align: left; text-overflow: ellipsis; white-space: nowrap; } .cad-block-library__name:hover { background: var(--cad-chrome-sunken); } .cad-block-library__actions { display: flex; gap: 6px; margin-top: 8px; } .cad-block-library__actions button { flex: 1; padding: 4px 0; border: 1px solid var(--cad-line); border-radius: 3px; background: transparent; color: var(--cad-text-dim); font-size: 11px; } /* 도각 자리표 패널 — 도각 편집으로 도면을 실었을 때만 뜬다 (2026-09-06 사용자 지시로 부모 사이드바에서 캐드 안으로 옮김). 도면 오른쪽 위, 리본 아래에 붙는다. */ .cad-frame-tokens { position: fixed; /* 오른쪽 위는 진행단계 패널이 쓴다 — 아래쪽(상태막대·명령행 위)에 붙인다. */ right: 12px; bottom: calc(var(--cad-status-height) + var(--cad-command-height) + 8px); z-index: 3; max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; width: 236px; padding: 8px; border: 1px solid var(--cad-line); border-radius: 6px; background: var(--cad-chrome-raised); box-shadow: var(--shadow-lg); color: var(--cad-text); } .cad-frame-tokens__header { color: var(--cad-text-dim); font-size: 11px; line-height: 1.4; } .cad-frame-tokens__group { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; } .cad-frame-tokens__title { width: 100%; color: var(--cad-text-dim); font-size: 11px; } .cad-frame-tokens__button { padding: 3px 7px; border: 1px solid var(--cad-line); border-radius: 4px; background: var(--cad-chrome); color: var(--cad-text); font-size: 11px; cursor: pointer; } .cad-frame-tokens__button:hover { background: var(--cad-accent-soft, var(--cad-chrome-raised)); } /* 자리표 칸 크기 입력 (2026-09-06) */ .cad-frame-tokens__size { display: flex; align-items: center; gap: 4px; color: var(--cad-text-dim); font-size: 11px; } .cad-frame-tokens__size input { width: 64px; padding: 2px 4px; border: 1px solid var(--cad-line); border-radius: 4px; background: var(--cad-chrome); color: var(--cad-text); font-size: 11px; }