@charset "UTF-8";
/* ==========================================================================
   CDMS 관리콘솔 — KRDS(디지털 정부서비스 디자인시스템) 기반 스타일
   토큰: krds-tokens.css. WCAG 2.1 AA 준수(대비/포커스/터치영역).
   ========================================================================== */
* { box-sizing: border-box; }
/* 폼 컨트롤은 폰트를 상속하지 않는 게 HTML 기본이다(Arial 13.3px). 전역에서 한 번에 상속(14번 #11, 수정요청 46).
   단축 속성 font는 line-height까지 상속해 컨트롤이 2~5px씩 커진다(본문 행간) → 행간만 기본값으로 되돌린다(16번 점검표 1) */
input, select, textarea, button { font: inherit; line-height: normal; }
/* hidden 속성이 항상 이기도록: .btn 등 display를 지정하는 작성자 스타일이
   브라우저 기본 [hidden]{display:none}을 덮어써 숨김이 무시되는 문제 방지 */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
    margin: 0; background: var(--krds-bg); color: var(--krds-text);
    font-family: var(--krds-font); font-size: var(--krds-fs-body); line-height: var(--krds-lh);
    -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: 1.35; color: var(--krds-text); }
h1 { font-size: var(--krds-fs-h1); }
h2 { font-size: var(--krds-fs-h2); }
h3 { font-size: var(--krds-fs-h3); }
p { margin: 0; }
a { color: var(--krds-link); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--krds-link-hover); }
code { background: var(--krds-gray-5); padding: 2px 6px; border-radius: var(--krds-radius-sm);
    font-size: var(--krds-fs-xs); font-family: ui-monospace, "D2Coding", monospace; color: var(--krds-text); }
.muted { color: var(--krds-text-sub); }
:focus-visible { outline: 2px solid var(--krds-primary-50); outline-offset: 2px; }
/* 브라우저 기본 표면(T9, 14번 #9): 체크박스·라디오 강조색은 여기 한 곳에서만, 선택색은 브랜드 연한 톤 */
:root { accent-color: var(--krds-primary-50); }
::selection { background: var(--krds-primary-10); color: var(--krds-text); }

/* 접근성: 화면리더 전용 텍스트 */
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ── 건너뛰기 링크 (Skip Link) ── */
.skip-link {
    position: absolute; left: 50%; top: -60px; transform: translateX(-50%);
    z-index: 1000; background: var(--krds-primary-60); color: var(--krds-on-primary); padding: 10px 20px;
    border-radius: 0 0 var(--krds-radius) var(--krds-radius); text-decoration: none; font-weight: 700;
    transition: top .15s ease;
}
.skip-link:focus { top: 0; color: var(--krds-on-primary); }
/* 건너뛰기 다음 '고대비 보기'(D87) — 건너뛰기 링크와 같은 모양, 단추라 테두리·글꼴을 맞춘다 */
.skip-contrast { border: 0; font: inherit; font-weight: 700; cursor: pointer; }
.skip-contrast:focus { top: 0; }
.skip-contrast:focus-visible { outline: 3px solid var(--krds-on-primary); outline-offset: -5px; }

/* ── 헤더 (Identifier + GNB) ── */
/* 고정(sticky) 헤더가 아니라 내용과 함께 스크롤되는 면 — 그림자 없이 아래 테두리로 구분(14번 #13, T13) */
.site-header { background: var(--krds-surface); border-bottom: 1px solid var(--krds-gray-10); }
.site-header-inner {
    max-width: var(--krds-container); margin: 0 auto; padding: 0 var(--krds-sp-6);
    height: 64px; display: flex; align-items: center; justify-content: space-between; gap: var(--krds-sp-6);
}
.brand-identifier { display: flex; align-items: center; gap: var(--krds-sp-3); text-decoration: none; }
/* 동반 DB 심볼 — 비율 318:204, 최소 높이 24px. 색을 바꾸지 않는다 */
.brand-symbol { display: block; height: 32px; width: auto; flex-shrink: 0; }
/* 고객사 CI(D62) — 높이는 .brand-symbol(머리글 32px·로그인 48px), 가로로 긴 CI는 160px에서 비율대로 줄인다 */
.brand-logo { max-width: 160px; object-fit: contain; }
:root[data-theme="high-contrast"] .brand-symbol { background: var(--krds-static-white); padding: 4px; border-radius: var(--krds-radius-sm); }
.brand-name { font-size: var(--krds-fs-h3); font-weight: 700; color: var(--krds-text); }
/* 부제는 서비스 이름 아래 한 줄(D97, DBDS AppShell 2.9판) — 전에는 inline이라 이름에 바로 붙어 보였다 */
.brand-identifier > span { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.brand-sub { font-size: var(--krds-fs-xs); color: var(--krds-text-weak); }
.header-user { display: flex; align-items: center; gap: var(--krds-sp-3); font-size: var(--krds-fs-sm); }
.header-user .user-name { font-weight: 700; }

/* ── 레이아웃: 사이드 내비 + 본문 ── */
/* 페이지 높이 flex 체인(14번 #19, 16번 3-2): body가 화면 높이를 잡고 .layout이 남는 높이를 받는다 → 짧은 페이지도 푸터가 바닥,
   불필요한 세로 스크롤 0. 예전 min-height: calc(100vh - 64px - 90px)는 실제 헤더 99·푸터 101px와 어긋나 46px 넘쳤다.
   width:100% — 세로 flex의 자식에 margin:auto를 주면 stretch가 꺼져 내용 폭으로 줄어든다 */
.shell-page { display: flex; flex-direction: column; min-height: 100vh; }
.layout { flex: 1 0 auto; width: 100%; max-width: var(--krds-container); margin: 0 auto; display: flex; gap: 0; }
.side-nav { width: 232px; flex-shrink: 0; background: var(--krds-surface);
    border-right: 1px solid var(--krds-gray-10); padding: var(--krds-sp-2) 0; }
.side-nav ul { list-style: none; margin: 0; padding: 0; }

/* ── KRDS 사이드내비: 그룹 폴딩(디스클로저) ── */
.nav-group-toggle {
    display: flex; align-items: center; gap: var(--krds-sp-2); width: 100%;
    padding: var(--krds-sp-3) var(--krds-sp-5); background: none; border: none; cursor: pointer;
    font-family: inherit; font-size: var(--krds-fs-body); font-weight: 700; color: var(--krds-text);
    text-align: left; transition: background .12s;
}
.nav-group-toggle:hover { background: var(--krds-gray-5); }
.nav-group-toggle:focus-visible { outline: none; box-shadow: var(--krds-focus); }
/* chevron: 펼침=아래(▾), 접힘=오른쪽(▸) */
.nav-group-toggle::after {
    content: ""; flex-shrink: 0; width: 8px; height: 8px; margin-left: auto; margin-top: -3px;
    border-right: 2px solid var(--krds-text-sub); border-bottom: 2px solid var(--krds-text-sub);
    transform: rotate(45deg); transition: transform .18s;
}
.nav-group-toggle[aria-expanded="false"]::after { transform: rotate(-45deg); margin-top: 0; }

/* 하위 메뉴 항목 (불릿 + 들여쓰기) */
.side-nav a {
    display: flex; align-items: center; gap: var(--krds-sp-2);
    padding: 9px var(--krds-sp-5) 9px var(--krds-sp-8);
    color: var(--krds-text-sub); text-decoration: none; font-size: var(--krds-fs-sm); font-weight: 400;
    border-left: 3px solid transparent; position: relative;
}
.side-nav a::before {
    content: ""; position: absolute; left: var(--krds-sp-5); width: 3px; height: 3px;
    border-radius: 50%; background: var(--krds-text-weak);
}
.side-nav a:hover { background: var(--krds-primary-5); color: var(--krds-primary-text); }
.side-nav a:hover::before { background: var(--krds-primary-60); }
.side-nav a[aria-current="page"] {
    background: var(--krds-secondary-5); color: var(--krds-primary-text);
    border-left-color: var(--krds-primary-50); font-weight: 700;
}
.side-nav a[aria-current="page"]::before { background: var(--krds-primary-50); }
.main { flex: 1; min-width: 0; padding: var(--krds-sp-6) var(--krds-sp-8) var(--krds-sp-12); }

/* ── 브레드크럼 ── */
.breadcrumb { margin-bottom: var(--krds-sp-4); }
.breadcrumb ol { list-style: none; display: flex; flex-wrap: wrap; align-items: center;
    gap: var(--krds-sp-1); margin: 0; padding: 0; font-size: var(--krds-fs-sm); color: var(--krds-text-sub); }
.breadcrumb li { display: flex; align-items: center; gap: var(--krds-sp-1); }
.breadcrumb li:not(:last-child)::after { content: "›"; color: var(--krds-text-weak); margin-left: var(--krds-sp-1); }
/* 패딩+음수 마진: 시각 위치는 그대로 두고 클릭 영역만 넓힌다 — '홈'이 12x21px로
   KRDS 마우스 최소(17x17)에 미달했다. KRDS 브레드크럼 편도 충분한 클릭 영역과
   인접 링크 간 간격을 요구한다(수정요청 46). */
.breadcrumb a { color: var(--krds-text-sub); text-decoration: none;
    padding: 4px 6px; margin: -4px -6px; border-radius: var(--krds-radius-sm); }
.breadcrumb a:hover { background: var(--krds-gray-5); }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb [aria-current="page"] { color: var(--krds-text); font-weight: 700; }

.page-header { display: flex; justify-content: space-between; align-items: center;
    gap: var(--krds-sp-4); margin-bottom: var(--krds-sp-5); flex-wrap: wrap; }

/* ── 카드 ── */
.card { background: var(--krds-surface); border: 1px solid var(--krds-gray-10);
    border-radius: var(--krds-radius-card); padding: var(--krds-sp-6); margin-bottom: var(--krds-sp-5); }
/* 직계(>)가 아닌 자손 선택 — 역할/권한처럼 h2가 .page-header 등에 한 겹 싸이면
   직계 규칙을 못 받아 22px로 튀었다(수정요청 46). 섹션 제목은 카드 어디에 있든 18px. */
.card h2 { margin-bottom: var(--krds-sp-4); font-size: var(--krds-fs-h3); }
/* 시스템 설정 행(FINDING-007): 이름 → 한 줄 설명 → 내부 키(보조), 값 옆 단위 */
.settings-table .setting-label { display: block; font-weight: 700; }
.settings-table .setting-desc { margin-top: 2px; font-size: var(--krds-fs-caption); color: var(--krds-text-sub); max-width: 52ch; }
/* 숫자 칸은 자릿수 폭(D28) — .form-row input:not(...)(0,3,1)의 flex: 1 1 12rem이 늘려 262px가 됐다.
   같은 (0,3,1)로는 파일 뒤쪽의 .form-row 규칙에 진다 → td를 더해 (0,3,2), flex까지 고정(16번 1-1) */
.settings-table td .form-row input.setting-num { flex: 0 0 96px; width: 96px; }
.settings-table .setting-unit { font-size: var(--krds-fs-ui); color: var(--krds-text-sub); }

/* 입력 아래 보조 안내(T19 FINDING-001: 배포할 승인 콘텐츠가 없을 때) */
.field-hint { margin-top: var(--krds-sp-1); font-size: var(--krds-fs-caption); color: var(--krds-text-sub); }
/* 배포 단계형 폼 제출 비활성 이유(T18, #20①) — 버튼 바로 옆 보조 문구 */
.wizard-submit-reason { font-size: var(--krds-fs-caption); color: var(--krds-text-sub); }

/* 표 구역(T8, 14번 #8): 표 하나뿐인 구역은 카드로 감싸지 않는다 — 테두리는 .table-wrap 한 겹만.
   제목 크기는 카드 섹션 제목과 같은 층위(18px), 구역 사이는 카드보다 넓게 띄워 테두리 없이도 구분 */
.table-section { margin-bottom: var(--krds-sp-8); }
.table-section > h2 { margin-bottom: var(--krds-sp-2); font-size: var(--krds-fs-h3); }
.table-section > p { margin-bottom: var(--krds-sp-3); }

/* ── 탭 (KRDS Tabs) ── */
.tabs { display: flex; gap: var(--krds-sp-1); border-bottom: 2px solid var(--krds-border);
    margin-bottom: var(--krds-sp-6); }
/* button(htmx 탭)과 a(링크 탭) 모두 지원 — 링크는 밑줄 제거 + 세로 정렬 필요 */
/* background-clip: padding-box 필수 — 탭은 margin-bottom:-2px로 컨테이너의 2px 경계선 위를
   덮고 있고, 배경은 기본값(border-box)이면 자기 border 영역까지 칠한다. 그래서 hover 배경이
   그 구간의 경계선을 가려 선이 끊겨 보였다(수정요청 42). padding-box면 배경이 border 앞에서
   멈춰 경계선이 그대로 비친다. */
.tab {
    appearance: none; background: none; background-clip: padding-box;
    border: none; border-bottom: 3px solid transparent;
    margin-bottom: -2px; padding: var(--krds-sp-3) var(--krds-sp-5); min-height: 48px;
    display: inline-flex; align-items: center; text-decoration: none;
    font-family: inherit; font-size: var(--krds-fs-body); font-weight: 700; cursor: pointer;
    color: var(--krds-text-sub); transition: color .12s, border-color .12s;
}
a.tab:hover { text-decoration: none; }
/* background-color로 지정 — background 단축을 쓰면 .tab의 background-clip:padding-box가
   기본값(border-box)으로 되돌아가 hover 배경이 다시 경계선을 덮는다 */
.tab:hover { color: var(--krds-text); background-color: var(--krds-gray-5); }
/* 글자는 primary-60 — 탭은 페이지 배경(--krds-bg) 위라 primary-50 글자가 4.17:1로 미달(14번 #16). 밑줄은 원색 유지 */
.tab.is-active { color: var(--krds-primary-text); border-bottom-color: var(--krds-primary-50); }
.tab:focus-visible { outline: none; box-shadow: var(--krds-focus); border-radius: var(--krds-radius-sm); }

/* ── 버튼 / 링크 ── */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--krds-sp-2);
    min-height: 44px; padding: 0 var(--krds-sp-5); border: 1px solid var(--krds-border);
    border-radius: var(--krds-radius); background: var(--krds-surface); color: var(--krds-text);
    font-family: inherit; font-size: var(--krds-fs-sm); font-weight: 700; cursor: pointer;
    text-decoration: none; transition: background .12s, border-color .12s;
    white-space: nowrap;   /* 좁은 칸에서 '보/기'처럼 한 글자씩 꺾이지 않게(T16) */
}
.btn:hover { background: var(--krds-gray-5); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--krds-primary-50); border-color: var(--krds-primary-50); color: var(--krds-on-primary); }
.btn-primary:hover { background: var(--krds-primary-60); border-color: var(--krds-primary-60); }
.btn-primary:active { background: var(--krds-primary-70); }
.btn-danger { background: var(--krds-critical); border-color: var(--krds-critical); color: var(--krds-on-primary); }
.btn-danger:hover { background: var(--krds-critical-hover); border-color: var(--krds-critical-hover); }
.btn-sm { min-height: 34px; padding: 0 var(--krds-sp-3); font-size: var(--krds-fs-xs); }
.btn-block { width: 100%; }
.inline { display: inline; }

/* ── 폼 (반응형 2열 그리드) ── */
.form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--krds-sp-4) var(--krds-sp-5); align-items: start; max-width: 920px; }
/* 필드 셀: 라벨 위 + 입력 아래 (한 행에 2개) */
.form .field { display: flex; flex-direction: column; min-width: 0; }
.form .field > label { margin-bottom: var(--krds-sp-2); }
/* 전체폭: 긴 필드·체크박스그룹·버튼행·소제목·설명·알림(나타날 때 옆 칸을 밀지 않게, 16번 2-5), 그리고 래핑 안 된 직계요소(안전 폴백) */
.form .field-full, .form > fieldset, .form > .form-actions, .form > .form-row, .form > .check,
.form > h2, .form > .muted, .form > .alert, .form > button, .form > .btn,
.form > label, .form > input, .form > select, .form > textarea { grid-column: 1 / -1; }
/* 버튼·체크박스는 전체폭 셀에서 좌측 정렬(늘어나지 않게) */
.form > button, .form > .btn, .form > .check { justify-self: start; }

.form label { font-weight: 700; font-size: var(--krds-fs-sm); }
.form input[type=text], .form input[type=password], .form input[type=email],
.form input[type=number], .form input[type=search], .form input[type=date],
.form input[type=time], .form input[type=datetime-local], .form input[type=file],
.form select, .form textarea, .search {
    display: block; width: 100%; min-height: 44px;
    padding: 10px var(--krds-sp-3);
    /* 입력 테두리는 DBDS input-border(바탕과 3:1 이상, D73-1) — border-gray-light(1.53:1)는 칸 경계가 안 보였다 */
    border: 1px solid var(--krds-border-strong); border-radius: var(--krds-radius);
    font-family: inherit; font-size: var(--krds-fs-body); color: var(--krds-text); background: var(--krds-surface);
}
.form textarea { min-height: 96px; resize: vertical; }
.form input:focus, .form select:focus, .form textarea:focus, .search:focus {
    outline: none; border-color: var(--krds-primary-50); box-shadow: var(--krds-focus); }
.form input[aria-invalid="true"], .form select[aria-invalid="true"], .form textarea[aria-invalid="true"] {
    border-color: var(--krds-critical); }
.field-error { color: var(--krds-critical-text); font-size: var(--krds-fs-sm); margin-top: var(--krds-sp-1); font-weight: 400; }
.form fieldset { border: 1px solid var(--krds-gray-10); border-radius: var(--krds-radius);
    margin: 0; padding: var(--krds-sp-3) var(--krds-sp-4); }
.form legend { font-weight: 700; font-size: var(--krds-fs-sm); padding: 0 var(--krds-sp-2); }
.check { display: inline-flex; align-items: center; gap: var(--krds-sp-2); font-weight: 400;
    margin: var(--krds-sp-1) var(--krds-sp-4) var(--krds-sp-1) 0; min-height: 32px; cursor: pointer; }
.check input { width: 18px; height: 18px; }
/* 표 체크박스의 클릭 영역(T15) — 맨 체크박스는 CSS로 영역을 못 넓혀 label로 감싼다. 터치에서는 44px(coarse 블록) */
.check-hit { display: inline-flex; align-items: center; justify-content: center; cursor: pointer; vertical-align: middle; }
.form-actions { display: flex; gap: var(--krds-sp-2); margin-top: var(--krds-sp-3); flex-wrap: wrap; }
/* 인라인 폼(.form-row): 그리드 대신 한 줄 배치 유지 */
.form-row { display: flex; gap: var(--krds-sp-2); align-items: center; flex-wrap: wrap; }
.form-row label { margin-bottom: 0; }
/* .form input[type=..]{width:100%}보다 특이도를 높여, 인라인 폼 입력은 한 줄에서 유연 배치 */
.form-row input:not([type=checkbox]):not([type=radio]), .form-row select {
    display: inline-block; width: auto; min-width: 0; margin-top: 0; flex: 1 1 12rem;
}
.form-row button, .form-row .btn { flex: 0 0 auto; }
.search { margin-bottom: var(--krds-sp-4); max-width: 420px; }

/* ── 배포 대상 선택 카드 그리드 (디바이스/그룹) ── */
.target-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: var(--krds-sp-3); }
.target-card {
    display: flex; flex-direction: column; gap: 2px; min-width: 0; cursor: pointer;
    padding: var(--krds-sp-3) var(--krds-sp-4); margin: 0; font-weight: 400;
    background: var(--krds-surface); border: 1px solid var(--krds-border);
    border-radius: var(--krds-radius); transition: border-color .12s, background .12s;
}
.target-card:hover { border-color: var(--krds-border-strong); background: var(--krds-gray-5); }
/* 선택 시 강조 (테두리 굵기 변화로 인한 이동 방지: padding 보정) */
.target-card:has(input:checked) {
    border: 2px solid var(--krds-primary-50); background: var(--krds-primary-5);
    padding: calc(var(--krds-sp-3) - 1px) calc(var(--krds-sp-4) - 1px);
}
.target-card:focus-within { outline: none; box-shadow: var(--krds-focus); }
.target-head { display: flex; align-items: center; gap: var(--krds-sp-2); margin-bottom: var(--krds-sp-2); }
.target-head input[type=checkbox] { width: 18px; height: 18px; flex-shrink: 0;
    cursor: pointer; }
/* 이름이 카드의 식별자라 한 줄 말줄임(…)으로 자르지 않는다 — 두 줄까지 보이고 그 이상만 줄임(T19 FINDING-004) */
.target-name { flex: 1; min-width: 0; font-weight: 700; font-size: var(--krds-fs-sm);
    overflow: hidden; overflow-wrap: anywhere; word-break: keep-all;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.target-attr { display: flex; justify-content: space-between; gap: var(--krds-sp-2);
    font-size: var(--krds-fs-xs); color: var(--krds-text-sub); }
.target-attr b { font-weight: 400; color: var(--krds-text-weak); flex-shrink: 0; }
.target-attr > span { text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 배포 단계형 폼 (D24) ── */
/* .form의 2열 그리드 대신 단계 카드를 세로로 쌓는다 */
.form.deploy-wizard { display: flex; flex-direction: column; align-items: stretch;
    gap: var(--krds-sp-5); max-width: none; }
/* 조건부 일정/입력 영역은 내부에서 2열 그리드 */
.deploy-wizard .wizard-cond { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--krds-sp-4) var(--krds-sp-5); align-items: start; max-width: 920px; }
.deploy-wizard .wizard-cond > .field-full, .deploy-wizard .wizard-cond > fieldset,
.deploy-wizard .wizard-cond > p { grid-column: 1 / -1; }
.deploy-wizard .wizard-cond[hidden] { display: none; }
.wizard-step h2 { display: flex; align-items: center; gap: var(--krds-sp-3); }
.step-no { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 26px; height: 26px; border-radius: 50%; font-size: var(--krds-fs-sm); font-weight: 700;
    background: var(--krds-primary-50); color: var(--krds-on-primary); }
.option-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--krds-sp-3); margin-bottom: var(--krds-sp-4); }
.option-card { display: flex; flex-direction: column; gap: 2px; cursor: pointer; margin: 0;
    padding: var(--krds-sp-4); font-weight: 400;
    background: var(--krds-surface); border: 1px solid var(--krds-border);
    border-radius: var(--krds-radius); transition: border-color .12s, background .12s; }
.option-card:hover { border-color: var(--krds-border-strong); background: var(--krds-gray-5); }
/* 네이티브 라디오는 13x13이라 KRDS 마우스 최소(17x17) 미달 — col-check 체크박스와 같은 18px */
.option-card input[type=radio] { width: 18px; height: 18px; }
.option-card:has(input:checked) { border: 2px solid var(--krds-primary-50);
    background: var(--krds-primary-5); padding: calc(var(--krds-sp-4) - 1px); }
.option-card:focus-within { outline: none; box-shadow: var(--krds-focus); }
.option-card input[type=radio] { position: absolute; opacity: 0; pointer-events: none; }
.option-card.is-disabled { opacity: .45; cursor: not-allowed; }
.option-card.is-disabled:hover { border-color: var(--krds-border); background: var(--krds-surface); }
.option-title { font-weight: 700; font-size: var(--krds-fs-ui); } /* 없는 --krds-fs-md였다 — 실제로 보이던 14px 그대로(R4-6) */
.option-card:has(input:checked) .option-title { color: var(--krds-primary-text); }
.option-desc { font-size: var(--krds-fs-xs); color: var(--krds-text-sub); }
.wizard-cond { margin-top: var(--krds-sp-4); }
.wizard-submit { display: flex; align-items: center; justify-content: flex-end;
    gap: var(--krds-sp-4); padding: var(--krds-sp-4) var(--krds-sp-5);
    background: var(--krds-gray-5); border: 1px solid var(--krds-border);
    border-radius: var(--krds-radius); margin-top: var(--krds-sp-4); }


/* 상태 1줄(T7, 14번 #7) — 상태 배지 바로 아래 보조 문구 */
.status-line { margin: var(--krds-sp-1) 0 0; font-size: var(--krds-fs-xs); color: var(--krds-text-sub); }
.ed-lifecycle { display: inline-flex; align-items: center; gap: var(--krds-sp-2); min-width: 0; }
.ed-lifecycle .status-line { margin: 0; max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 디바이스 카드 그리드 (D25 목록 카드형 전환) ── */
.device-toolbar { display: flex; align-items: center; gap: var(--krds-sp-4); flex-wrap: wrap;
    margin-bottom: var(--krds-sp-4); }
.device-toolbar .bulk-bar { margin-bottom: 0; }
.device-toolbar .search { margin-left: auto; margin-bottom: 0; max-width: 260px; }
.select-all-label { display: inline-flex; align-items: center; gap: var(--krds-sp-2);
    font-size: var(--krds-fs-sm); cursor: pointer; }
.select-all-label input[type=checkbox] { width: 18px; height: 18px;
    cursor: pointer; }
/* 이름은 상세로 이동하는 링크 — 카드(label) 클릭 선택과 구분 */
.device-name { color: var(--krds-primary-text); text-decoration: none; }
.device-name:hover { text-decoration: underline; }
/* 카드 하단: 사용 중 배지 + 상세 버튼 */
.device-foot { display: flex; align-items: center; gap: var(--krds-sp-2); flex-wrap: wrap;
    margin-top: var(--krds-sp-2); padding-top: var(--krds-sp-2);
    border-top: 1px solid var(--krds-border); }
.device-foot .btn { margin-left: auto; }
.device-foot-none { font-size: var(--krds-fs-xs); }


/* 일괄 처리 바 (승인함 등) */
.bulk-bar { display: flex; align-items: center; gap: var(--krds-sp-2); flex-wrap: wrap;
    margin-bottom: var(--krds-sp-4); }
.bulk-bar .bulk-count { margin-left: var(--krds-sp-2); font-size: var(--krds-fs-sm); }

/* 선택했을 때만 등장하는 액션 — 평소 비활성 버튼이 자리를 차지하지 않게 한다.
   JS(wireBulkActions)가 선택 건수에 따라 is-visible을 토글한다.
   자체 줄을 만들면 체크 순간 목록이 밀려 다음 클릭이 어긋나므로(수정요청 30),
   이미 있는 줄(탭/툴바)의 빈 오른쪽에 얹어 레이아웃 이동을 0으로 만든다. */
.bulk-bar-inline { display: none; align-items: center; gap: var(--krds-sp-2); margin-bottom: 0; }
.bulk-bar-inline.is-visible { display: flex; }
.bulk-bar-inline .bulk-count { margin-left: 0; font-weight: 700; color: var(--krds-primary-text); }
.bulk-note { font-size: var(--krds-fs-xs); }

/* 탭 줄 오른쪽을 선택 액션 자리로 */
.tabs-with-actions { justify-content: space-between; align-items: center; flex-wrap: wrap; }
.tabs-with-actions .tabs-list { display: flex; gap: var(--krds-sp-1); }
.tabs-with-actions .bulk-bar-inline { padding-bottom: var(--krds-sp-2); }
/* 좁아지면 안내 문구부터 버린다 — 건수와 버튼이 우선 */
@media (max-width: 899px) { .tabs-with-actions .bulk-note { display: none; } }
/* ── 숫자 입력 (D28) ──
   KRDS p435: 마우스 17x17, 터치 44x44 이상. 네이티브 화살표는 약 15x16이라 마우스 기준에도 미달.
   KRDS가 입력 수단별로 두 값을 제시하므로 pointer 미디어 쿼리로 그대로 대응한다.
   ('스피너'는 KRDS에서 로딩 표시를 뜻해 number-stepper로 명명) */
/* align-self:start 필수 — .field가 flex-column이라 그냥 두면 stretch되어 전면폭이 된다
   (inline-flex도 flex 아이템이 되면 블록화되므로 display만으로는 못 막는다) */
.number-stepper { display: inline-flex; align-items: center; align-self: start; width: auto;
    border: 1px solid var(--krds-border-strong); border-radius: var(--krds-radius);
    background: var(--krds-surface); overflow: hidden; }
.stepper-btn { flex-shrink: 0; width: 32px; height: 32px; padding: 0;
    border: none; border-radius: 0; background: transparent;
    font-family: inherit; font-size: 16px; font-weight: 700; line-height: 1;
    color: var(--krds-text); cursor: pointer; }
.stepper-btn:hover { background: var(--krds-primary-5); color: var(--krds-primary-text); }
.stepper-btn:disabled { color: var(--krds-text-weak); background: transparent; cursor: default; }
.stepper-btn:focus-visible { outline: none; box-shadow: var(--krds-focus); }
/* .form의 전면폭 규칙을 이긴다 — 숫자는 값 길이에 맞춰 폭을 고정(KRDS 입력 필드 편) */
.number-stepper input[type=number] {
    width: var(--stepper-input-w, 32px); min-height: 32px; padding: 0 2px; text-align: center;
    border: none; border-left: 1px solid var(--krds-border); border-right: 1px solid var(--krds-border);
    border-radius: 0; font-family: inherit; font-size: var(--krds-fs-sm); color: var(--krds-text);
    background: transparent; }
.number-stepper input:focus { outline: none; box-shadow: none; background: var(--krds-primary-5); }
/* 네이티브 화살표 제거 — 버튼이 대체한다 */
.number-stepper input::-webkit-outer-spin-button,
.number-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.number-stepper input[type=number] { -moz-appearance: textfield; appearance: textfield; }
/* 자릿수별 입력 폭: 버튼 64px을 더해 총 96 / 112 / 128 / 160px. 폭은 변수로 — 아래 .form-row 규칙도 같은 값을 쓴다 */
.number-stepper[data-digits="3"] { --stepper-input-w: 32px; }
.number-stepper[data-digits="4"] { --stepper-input-w: 48px; }
.number-stepper[data-digits="5"] { --stepper-input-w: 64px; }
.number-stepper[data-digits="6"],
.number-stepper[data-digits="7"] { --stepper-input-w: 96px; }
/* 인라인 폼(.form-row) 안의 스테퍼: .form-row input:not(..):not(..)(0,3,1)의 flex: 1 1 12rem·width: auto가 자릿수 폭을 덮어
   277px가 됐다(R3-4, 16번 1-1 재발). (0,3,2)로 이기고 같은 변수 폭으로 되돌린다 — 공용 규칙의 특이도는 건드리지 않는다
   (올리면 옛 설정 표의 .setting-num 덧댐(0,3,2)이 진다) */
.form-row span.number-stepper input[type=number] { flex: 0 0 auto; width: var(--stepper-input-w, 32px); }
/* 터치 기기: KRDS 44x44 충족 */
/* ── 접히는 카드 (수정요청 40) ──
   details/summary라 접기·키보드(Enter/Space)·스크린리더 확장 상태가 네이티브로 동작한다.
   요약줄에 건수를 두어 열지 않고도 내용 유무를 알 수 있다. 다른 카드에도 재사용 가능. */
.card-fold { padding: 0; }
.card-fold > summary { display: flex; align-items: center; gap: var(--krds-sp-2);
    padding: var(--krds-sp-4); cursor: pointer; list-style: none; min-height: 44px; }
.card-fold > summary::-webkit-details-marker { display: none; }
.card-fold > summary::before { content: "▸"; color: var(--krds-primary-50); font-size: var(--krds-fs-caption); }
.card-fold[open] > summary::before { content: "▾"; }
.card-fold > summary:hover { background: var(--krds-gray-5); }
.card-fold > summary:focus-visible { outline: none; box-shadow: var(--krds-focus); }
.card-fold > summary h2 { margin: 0; }
.card-fold > *:not(summary) { padding: 0 var(--krds-sp-4) var(--krds-sp-4); }

/* ── 라디오 칩 (D29) ──
   겉모습은 세그먼트 토글, 속은 라디오. KRDS radio_chip 패턴.
   사각형 비율이 곧 답이라 글자를 읽기 전에 가로/세로가 구분된다. */
/* fieldset.chip-fieldset — `.form fieldset`(테두리+패딩 12/16px)을 이기려면 요소선택자를 더해야 한다.
   그냥 .chip-fieldset이면 우선순위가 낮아 덮여서, 다른 필드엔 없는 상자가 생기고
   셀 폭도 34px 깎였다(수정요청 41). */
fieldset.chip-fieldset { margin: 0; padding: 0; border: none; min-inline-size: 0; }
/* margin-bottom은 폼의 다른 라벨과 같은 8px — legend는 fieldset 내부라 .field의 간격이
   적용되지 않아, 직접 맞추지 않으면 방향 행만 3px 짧아진다 */
fieldset.chip-fieldset > legend { padding: 0; margin-bottom: var(--krds-sp-2);
    font-weight: 700; font-size: var(--krds-fs-sm); color: var(--krds-text); }
.chip-group { display: flex; gap: var(--krds-sp-2); }
/* 셀을 반씩 나눠 채우되(grow), 인라인 한 줄 폼에서는 min-width로 제 크기를 지킨다 */
.form-chip { flex: none; }
/* 라디오 자체는 숨기되 접근성 트리에는 남긴다 — display:none이면 키보드 조작이 사라진다 */
.form-chip input { position: absolute; width: 1px; height: 1px; opacity: 0; }
/* 아이콘을 옆으로 눕힌다: 세로 아이콘(26px)이 가로(15px)보다 커서 세로로 쌓으면
   칩 두 개의 높이가 달라졌다(58 vs 71). 가로 배치면 아이콘 크기가 높이를 좌우하지 않는다. */
/* D86 고르는 칩 한 모양 — 36px 알약·14px·진한 회색 테두리, 고르면 옅은 주색 면 + 주색 테두리 + 굵게 + ✓(✓는 spa.css).
   전에는 44px 사각·고르면 테두리 2px(옆 칩이 밀림) — 목록 칩과 모양이 달랐다 */
.form-chip label { display: inline-flex; align-items: center; justify-content: center;
    gap: 6px; min-height: 36px; padding: 0 14px;
    border: 1px solid var(--krds-border-strong); border-radius: 999px;
    background: var(--krds-surface); cursor: pointer;
    font-size: var(--krds-fs-sm); font-weight: 400; color: var(--krds-text); }
.form-chip label:hover { background: var(--krds-gray-5); }
.form-chip input:checked + label { border-color: var(--krds-primary-50);
    background: var(--krds-primary-5); color: var(--krds-primary-text); font-weight: 700; }
.form-chip input:focus-visible + label { outline: none; box-shadow: var(--krds-focus); }
.form-chip input:disabled + label { background: var(--krds-gray-5); color: var(--krds-text-weak); cursor: default; }
.chip-shape { border: 2px solid currentColor; border-radius: 2px; flex-shrink: 0; }
/* 36px 칩에 들어가는 크기(DBDS 칩 1판: 가로 18×11 · 세로 11×18) */
.chip-land { width: 18px; height: 11px; }
.chip-port { width: 11px; height: 18px; }

/* 표 안 텍스트 링크: 행간에 눌려 16px 높이였다 — 시각 변화 없이 클릭 영역만 17px 이상으로 */
table td > a:not(.btn) { display: inline-block; padding: 3px 0; margin: -3px 0; }

.col-check { width: 40px; text-align: center; }
.col-check input[type=checkbox] { width: 18px; height: 18px; cursor: pointer; }

/* 인라인 폼(테이블 셀 등) 입력/셀렉트: KRDS 컴팩트(34px)로 통일, btn-sm과 정렬 */
form.inline input[type=text], form.inline input[type=password], form.inline input[type=number],
form.inline input[type=search], form.inline input[type=email], form.inline select {
    display: inline-block; min-height: 34px; padding: 4px var(--krds-sp-3); vertical-align: middle;
    border: 1px solid var(--krds-border); border-radius: var(--krds-radius);
    font-family: inherit; font-size: var(--krds-fs-sm); color: var(--krds-text); background: var(--krds-surface);
}
form.inline input:focus, form.inline select:focus {
    outline: none; border-color: var(--krds-primary-50); box-shadow: var(--krds-focus); }

/* ── 툴바: 검색 + 액션 버튼을 한 행에 (좁아지면 줄바꿈) ── */
.toolbar { display: flex; align-items: center; gap: var(--krds-sp-3);
    margin-bottom: var(--krds-sp-5); flex-wrap: wrap; }
.toolbar .search { flex: 1; min-width: 200px; max-width: none; margin-bottom: 0; }
.perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--krds-sp-1); margin-bottom: var(--krds-sp-4); }

/* ── 구조화 목록 / 테이블 ── */
/* 내용 면(카드·표 래퍼·통계 카드)은 8px, 12px(radius-lg)는 오버레이(모달·로그인 카드) 전용 — 14번 #13 */
/* position: relative — 표 안 .sr-only(position:absolute)가 스크롤 상자를 빠져나가 페이지 전체에 가로 스크롤을 만들었다(T16, 16번 3-5) */
.table-wrap { position: relative; overflow-x: auto; border: 1px solid var(--krds-gray-10); border-radius: var(--krds-radius-card); }
table { width: 100%; border-collapse: collapse; background: var(--krds-surface); }
caption { text-align: left; padding: var(--krds-sp-3) var(--krds-sp-4); font-weight: 700; color: var(--krds-text-sub); }
th, td { text-align: left; padding: 13px var(--krds-sp-4); border-bottom: 1px solid var(--krds-gray-10);
    font-size: var(--krds-fs-sm); vertical-align: middle;
    word-break: keep-all; }   /* 한글은 어절 단위로만 줄바꿈 — 좁으면 글자 단위로 쪼개지는 대신 표가 .table-wrap 안에서 스크롤(T16) */
thead th { background: var(--krds-gray-5); font-size: var(--krds-fs-xs); color: var(--krds-text-sub);
    font-weight: 700; border-bottom: 2px solid var(--krds-gray-20); white-space: nowrap; }
tbody tr:hover { background: var(--krds-primary-5); }
/* 숫자 폭 고정(T9): 행마다 자릿수 폭이 달라 열이 흔들리지 않게. 수량·용량 열은 .num으로 우측 정렬(날짜·시각은 좌측 유지) */
td, .badge,
.number-stepper input { font-variant-numeric: tabular-nums; }
th.num, td.num { text-align: right; }
tr:last-child td { border-bottom: none; }
/* 관리 칸은 table-cell 그대로 — display:flex로 바꾸면 셀이 행 높이를 따르지 않아 행마다 높이가 다를 때
   아래 테두리가 다른 칸보다 위에 그려진다(D65 썸네일 행 69px vs 칸 61px). 버튼 사이 간격은 margin으로 */
td.actions { white-space: nowrap; }
td.actions > * + * { margin-left: var(--krds-sp-1); }
td.detail { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: var(--krds-fs-xs); color: var(--krds-text-sub); }

/* ── 분류 배지 / 상태(D86, DBDS 칩·상태·배지 1판) ──
   분류 배지: 24px 옅은 회색 면·13px 굵게·테두리 없음(버튼과 헷갈리지 않게), 강조만 옅은 주색(.badge-primary).
   상태: 점 + 굵은 글자(상자 없음), 색 넷 — 정상 초록 · 진행/확인 주황 · 막힘 빨강(오프라인 포함, D87) · 꺼짐 회색. 뜻이 같으면 어디서나 같은 색 */
.badge { display: inline-flex; align-items: center; min-height: 24px; padding: 0 8px; border-radius: var(--krds-radius-sm);
    background: var(--krds-gray-5); color: var(--krds-text-sub); font-size: var(--krds-fs-caption); font-weight: 700;
    margin-right: var(--krds-sp-1); white-space: nowrap; vertical-align: middle; }
.badge-primary { background: var(--krds-primary-5); color: var(--krds-primary-text); }
.status { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: var(--krds-fs-sm); white-space: nowrap; }
/* 글자는 대비 4.5:1의 -text 토큰, 상태 점은 밝은 원색(--status-dot) — 14번 #16 */
.status::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--status-dot, currentColor); }
.status-ok, .status-ACTIVE, .status-APPROVED, .status-PUBLISHED, .status-ONLINE, .status-OK { color: var(--krds-success-text); --status-dot: var(--krds-success); }
.status-warn, .status-PENDING, .status-DRAFT { color: var(--krds-warning-text); --status-dot: var(--krds-warning); }
.status-bad, .status-LOCKED, .status-REJECTED, .status-ERROR, .status-OFFLINE { color: var(--krds-critical-text); --status-dot: var(--krds-critical); }
.status-off, .status-DISABLED, .status-ARCHIVED, .status-UNKNOWN { color: var(--krds-text-weak); --status-dot: var(--krds-gray-40); font-weight: 400; }

/* ── 알림 배너 (Critical alerts / flash) ── */
.alert { display: flex; gap: var(--krds-sp-3); padding: var(--krds-sp-4) var(--krds-sp-5);
    border-radius: var(--krds-radius); margin-bottom: var(--krds-sp-5); border: 1px solid transparent;
    font-size: var(--krds-fs-sm); }
.alert-icon { font-size: 18px; line-height: 1.4; }
/* 변형 4개(14번 #5) — 배경·보더·아이콘만 semantic 색, 글자는 --krds-text라 고대비에서 자동으로 #000.
   아이콘 기호(✓ ! ⚠ i)가 있어 색각 이상에도 구분된다. 예전 플래시 전용 클래스는 이것으로 통합·제거했다. */
.alert--success  { background: var(--krds-success-bg);  border-color: var(--krds-success);  color: var(--krds-text); }
.alert--critical { background: var(--krds-critical-bg); border-color: var(--krds-critical); color: var(--krds-text); }
.alert--warning  { background: var(--krds-warning-bg);  border-color: var(--krds-warning);  color: var(--krds-text); }
.alert--info     { background: var(--krds-info-bg);     border-color: var(--krds-info);     color: var(--krds-text); }
.alert--success  .alert-icon { color: var(--krds-success-text); }
.alert--critical .alert-icon { color: var(--krds-critical-text); }
.alert--warning  .alert-icon { color: var(--krds-warning-text); }
.alert--info     .alert-icon { color: var(--krds-info); }
.alert .alert-body { display: flex; flex-wrap: wrap; align-items: center; gap: var(--krds-sp-3); }

/* htmx 로딩 표시(14번 #4) — 고정 위치라 레이아웃 이동 0. 위치·폭은 krds-ui.js가 대상 영역에 맞춘다 */
.hx-loading { position: fixed; z-index: 1040; display: flex; align-items: center; justify-content: center;
    gap: var(--krds-sp-2); pointer-events: none; font-size: var(--krds-fs-sm); color: var(--krds-text-sub); }
.hx-loading > span { display: inline-flex; align-items: center; gap: var(--krds-sp-2);
    padding: var(--krds-sp-2) var(--krds-sp-4); background: var(--krds-surface);
    border: 1px solid var(--krds-border); border-radius: var(--krds-radius); box-shadow: var(--krds-shadow-2); }
[aria-busy="true"] { cursor: progress; }

/* ── 빈 상태 (14번 #3, D31) — 일러스트 없이 문구와 다음 행동만. 표 셀 안에서도 쓴다 ── */
.empty-state { text-align: center; padding: var(--krds-sp-8) var(--krds-sp-4); color: var(--krds-text-sub); }
.empty-state .empty-title { margin: 0; font-size: var(--krds-fs-body); font-weight: 700; color: var(--krds-text); }
.empty-state .empty-desc { margin: var(--krds-sp-1) 0 0; font-size: var(--krds-fs-sm); }
.empty-state .btn, .empty-state .empty-reset { margin-top: var(--krds-sp-3); }
/* 글자 링크만 inline-block — .btn은 자기 inline-flex(글자 세로 가운데)를 지킨다. 덮으면 a.btn 글자가 위로 붙는다(BrowserSurfaceIT) */
.empty-state .empty-reset { display: inline-block; }
/* 빈 상태 링크(#notice-title 등)로 접힌 폼이 열릴 때 입력란이 화면 맨 위에 붙어 라벨이 잘리지 않게 */
.card-fold :target { scroll-margin-top: var(--krds-sp-16); }

/* ── 페이지네이션 ── */
.pager { display: flex; gap: var(--krds-sp-1); align-items: center; justify-content: center;
    margin-top: var(--krds-sp-5); }
.pager .page-info { padding: 0 var(--krds-sp-3); color: var(--krds-text-sub); font-size: var(--krds-fs-sm); }

/* ── 통계 카드 (홈 대시보드) ── */
.stat-card { background: var(--krds-surface); border: 1px solid var(--krds-gray-10);
    border-radius: var(--krds-radius-card); padding: var(--krds-sp-5) var(--krds-sp-6); min-width: 0; }
/* 평소 중립색, 이상일 때만 의미색(FINDING-008) — 늘 파란색이라 '온라인 0/3'도 정상처럼 보였다. 아래 줄 문구로도 알린다(색만으로 구분하지 않음) */
.stat-num { font-size: var(--krds-fs-display); font-weight: 700; color: var(--krds-text); line-height: 1; }
.stat-num.is-warning { color: var(--krds-warning-text); }
.stat-num.is-critical { color: var(--krds-critical-text); }
.stat-danger { color: var(--krds-critical-text); font-weight: 700; }

/* 카드 제목 아래 한 줄 보조 문구 */
.card-sub { margin-top: calc(-1 * var(--krds-sp-3)); margin-bottom: var(--krds-sp-4);
    font-size: var(--krds-fs-xs); }

/* 배포 예약 타임라인 */
.timeline { list-style: none; display: flex; flex-direction: column; gap: var(--krds-sp-4); }
.timeline li { display: grid; grid-template-columns: 76px 10px 1fr; align-items: start;
    gap: var(--krds-sp-2); }

.form input[type=file] { display: block; margin-top: var(--krds-sp-1); font-size: var(--krds-fs-sm); }

/* ── 푸터 ── */
.site-footer { background: var(--krds-gray-80); color: var(--krds-inverse-text); margin-top: auto; }
.footer-inner { max-width: var(--krds-container); margin: 0 auto; padding: var(--krds-sp-6) var(--krds-sp-6); }
.footer-links { display: flex; flex-wrap: wrap; gap: var(--krds-sp-4); margin-bottom: var(--krds-sp-3);
    font-size: var(--krds-fs-sm); }
.footer-links a { color: var(--krds-inverse-text); text-decoration: none; }
.footer-links a:hover { text-decoration: underline; color: var(--krds-on-primary); }
.footer-links a.emphasis { color: var(--krds-on-primary); font-weight: 700; }
/* 어두운 푸터(gray-80) 위라 gray-40이 4.69:1 — text-weak로 바꾸면 2.81로 오히려 미달 */
/* 접근성 줄(D87) — 고대비 보기(단추) · 웹 접근성 안내 · Accessibility. 링크처럼 밑줄, 위에 옅은 구분선 */
.footer-a11y { display: flex; flex-wrap: wrap; align-items: center; gap: var(--krds-sp-2) var(--krds-sp-4); margin-bottom: var(--krds-sp-3);
    padding-top: var(--krds-sp-3); border-top: 1px solid var(--krds-gray-60); font-size: var(--krds-fs-sm); }
.footer-a11y a, .footer-a11y-btn { color: var(--krds-inverse-text); text-decoration: underline; text-underline-offset: 3px; }
.footer-a11y-btn { padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }
.footer-a11y a:hover, .footer-a11y-btn:hover { color: var(--krds-on-primary); }
.footer-a11y a:focus-visible, .footer-a11y-btn:focus-visible { outline: 2px solid var(--krds-on-primary); outline-offset: 2px; }
.footer-copy { font-size: var(--krds-fs-xs); color: var(--krds-inverse-text-weak); }
/* 고객사 CI가 있을 때 구축사 표기(D62) — 어두운 푸터 위 네이비 심볼은 흰 타일에(고대비 머리글과 같은 방식) */
.footer-powered { display: flex; align-items: center; gap: var(--krds-sp-2); margin-top: var(--krds-sp-1); }
.footer-powered img { display: block; box-sizing: content-box; background: var(--krds-static-white);
    padding: 2px 3px; border-radius: var(--krds-radius-sm); }

/* ── 로그인 ── */
.login-body { min-height: 100vh; display: flex; flex-direction: column; background: var(--krds-gray-5); }
.login-main { flex: 1; display: flex; align-items: center; justify-content: center; padding: var(--krds-sp-6); }
.login-card { background: var(--krds-surface); border: 1px solid var(--krds-gray-10);
    border-radius: var(--krds-radius-lg); box-shadow: var(--krds-shadow-2);
    padding: var(--krds-sp-10); width: 400px; max-width: 100%; }
.login-card .brand-symbol { height: 48px; margin: 0 auto var(--krds-sp-3); }
.login-card h1 { text-align: center; font-size: var(--krds-fs-h1); margin-bottom: var(--krds-sp-1); }
.login-card .login-sub { text-align: center; color: var(--krds-text-sub); margin-bottom: var(--krds-sp-6); font-size: var(--krds-fs-sm); }
.login-card label { display: block; margin-bottom: var(--krds-sp-4); font-weight: 700; font-size: var(--krds-fs-sm); }
.login-card input { display: block; width: 100%; min-height: 48px; padding: 12px var(--krds-sp-3);
    margin-top: var(--krds-sp-2); border: 1px solid var(--krds-border-strong); border-radius: var(--krds-radius); font-size: var(--krds-fs-body); }
.login-card input:focus { outline: none; border-color: var(--krds-primary-50); box-shadow: var(--krds-focus); }
/* 비밀번호 찾기 등 보조 링크 (D26) */
.login-links { text-align: center; margin-top: var(--krds-sp-4); font-size: var(--krds-fs-sm); }
/* 글자 링크 16px로 마우스 최소(17)에 미달 — 시각 크기는 두고 클릭 영역만 넓힌다(브레드크럼과 같은 방식, T15) */
.login-links a { display: inline-block; padding: 4px 6px; margin: -4px -6px; }
.login-links a { color: var(--krds-primary-text); }

/* 통합 로그인(D75) — 링크(<a>)로 그린 주 버튼. a:hover(0,1,1)가 .btn-primary(0,1,0) 글자색을 이기므로 다시 정한다(16번 1-1) */
a.btn-primary, a.btn-primary:hover { color: var(--krds-on-primary); }
.login-sso-hint { margin: var(--krds-sp-2) 0 0; text-align: center; font-size: var(--krds-fs-sm); color: var(--krds-text-sub); }
/* 비상 로그인(시스템관리자) — 접어 둔 아이디·비밀번호 양식 */
.login-emergency { margin-top: var(--krds-sp-6); padding-top: var(--krds-sp-4); border-top: 1px solid var(--krds-border); }
.login-emergency > summary { display: flex; align-items: center; gap: var(--krds-sp-2); min-height: 44px;
    cursor: pointer; list-style: none; font-size: var(--krds-fs-sm); font-weight: 700; color: var(--krds-text); }
.login-emergency > summary::-webkit-details-marker { display: none; }
.login-emergency > summary::before { content: "▸"; color: var(--krds-primary-text); font-size: var(--krds-fs-caption); }
.login-emergency[open] > summary::before { content: "▾"; }
.login-emergency > summary:focus-visible { outline: none; box-shadow: var(--krds-focus); }
.login-emergency > .form { margin-top: var(--krds-sp-3); }

/* ── 모달 (KRDS: role=dialog, 포커스 트랩은 JS) ── */
.modal-overlay { position: fixed; inset: 0; z-index: 1050; background: var(--krds-overlay);
    display: flex; align-items: center; justify-content: center; padding: var(--krds-sp-4); }
.modal { background: var(--krds-surface); border-radius: var(--krds-radius-lg); box-shadow: var(--krds-shadow-3);
    width: 440px; max-width: 100%; padding: var(--krds-sp-6); }
.modal h2 { margin-bottom: var(--krds-sp-3); }
.modal-actions { display: flex; gap: var(--krds-sp-2); justify-content: flex-end; margin-top: var(--krds-sp-6); }
/* 파급 행위 확인 3줄(T7 #7): 무엇을 / 어디에 / 되돌리기 — 라벨 열 고정폭 */
.modal-facts { display: grid; grid-template-columns: 5.5em 1fr; gap: var(--krds-sp-2) var(--krds-sp-3); margin: 0;
    font-size: var(--krds-fs-sm); }
/* SPA ConfirmDialog는 한 쌍(dt·dd)을 div.modal-fact로 감싼다 — 감싼 div가 격자 칸 하나를 통째로 차지해 라벨 열(5.5em)에
   '무엇을' 쌍 전체가 끼고 '어디에'가 옆 칸으로 갔다(v2.4 검수). 쌍마다 한 줄 전체를 쓰고 같은 열 폭을 이어받는다 */
.modal-fact { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; }
.modal-facts dt { color: var(--krds-text-sub); font-weight: 700; }
.modal-facts dd { margin: 0; color: var(--krds-text); overflow-wrap: anywhere; }

/* ==========================================================================
   에디터 (관리콘솔 내, KRDS 톤 적용)
   ========================================================================== */
/* 에디터 높이 (수정요청 35): 매직 상수를 쓰지 않는다.
   예전 `height: calc(100vh - 64px)`의 64는 실제 크롬(마스트헤드 34 + 헤더 65 = 99px)과 달라
   항상 35px 넘쳤다. 크롬 높이는 폰트·문구에 따라 변하므로 상수로 못 박으면 언제든 또 어긋난다.
   body → editor-shell → editor-main을 flex 체인으로 이어 남는 공간을 그대로 받는다. */
.editor-page { display: flex; flex-direction: column; height: 100vh; }
.editor-shell { flex: 1; min-height: 0; display: flex; }
.editor-main { max-width: none; display: flex; flex-direction: column; flex: 1; min-height: 0;
    padding: var(--krds-sp-3) var(--krds-sp-4); }
/* 상단 앱바: 나가기(유일한 탈출구) → 제목 → 저장 → 배지·상태 …… 버전 이력(우측) */
.editor-toolbar { display: flex; gap: 6px; align-items: center; margin-bottom: var(--krds-sp-3);
    padding-bottom: var(--krds-sp-3); border-bottom: 1px solid var(--krds-border); }
.ed-title { flex: 1; max-width: 420px; padding: 8px var(--krds-sp-3);
    border: 1px solid var(--krds-border-strong); border-radius: var(--krds-radius); min-height: 40px;
    font-size: var(--krds-fs-body); }
/* 남는 공간은 '버전 이력'이 흡수한다(수정요청 45).
   - 예전엔 .ed-title에 margin-right:auto를 걸어 오른쪽 묶음을 화면 끝에 고정했는데(수정요청 33),
     넓은 화면에서 빈 공간이 최대 1306px(툴바의 69%)까지 벌어져 시선이 크게 튀었다.
   - 그보다 앞서는 #ed-status/.ed-dirty에 margin-left:auto를 걸었는데, 인접 선택자가 표시 여부가
     아니라 DOM 인접성만 보는 탓에(.ed-dirty는 hidden이어도 DOM에 있음) status는 auto를 영영
     못 받았고, 배지가 뜨는 순간 저장이 오른쪽 끝으로 503px 튀었다.
   지금은 저장이 제목 바로 뒤에 오고 배지·상태가 그 '뒤'라, 배지가 나타나도 저장이 밀리지 않는다.
   신규 작성 화면에는 이 버튼이 없어 auto가 사라지지만, 전부 좌측 정렬이라 문제되지 않는다. */
.ed-versions-btn { margin-left: auto; }
.ed-sep { width: 1px; height: 24px; background: var(--krds-gray-10); margin: 0 4px; }
#ed-status { font-size: var(--krds-fs-sm); color: var(--krds-text-sub); }
/* 미저장 표시 — 이 화면은 저장 없이 나가면 작업이 사라지므로 상태를 상시 노출 */
.ed-dirty { font-size: var(--krds-fs-caption); font-weight: 700; padding: 2px 8px;
    border-radius: var(--krds-radius-sm);
    background: var(--krds-warning-bg); color: var(--krds-warning-text);
    /* 옆 상태 문구가 길어지면 배지가 눌려 두 줄(43px)이 되고 툴바가 커졌다(16번 2-2) — 눌리지 않게 */
    flex-shrink: 0; white-space: nowrap; }

/* 위젯 팔레트: 13개를 역할별 그룹으로 세로 배치.
   폭 112px = 타일 46 × 2열 + 간격 3 + 패딩 16. 타일이 세로형(46x45)이 되며 폭이 남아
   132 → 112로 조인다(수정요청 36). 104px까지 줄이면 타일이 42px이 되어 KRDS 터치 기준(44)에
   미달하므로 112가 하한. 캔버스가 폭 제약이라 줄인 20px은 그대로 캔버스가 가져간다. */
.editor-palette { width: 112px; flex-shrink: 0; overflow-y: auto;
    background: var(--krds-gray-5); border: 1px solid var(--krds-gray-10);
    border-radius: var(--krds-radius); padding: var(--krds-sp-2); }
/* 아이콘 스프라이트 정의부는 화면에 나오지 않는다 — <use>로만 참조 */
.palette-sprite { display: none; }
/* 전엔 aside의 aria-label뿐이라 보는 사용자에겐 '추가'라는 말이 없었다 */
/* 타일 라벨이 11px이라 제목이 14px(krds-fs-sm)이면 27% 커서 항목보다 도드라진다.
   12px로 낮춰 위계는 유지하되(12 굵게 > 11 굵게 > 11 보통) 무게를 맞춘다.
   그룹 라벨은 11px 유지 — 이미 KRDS 본문 최소(16px) 아래라 더 줄이면 가독성이 상한다. */
.palette-title { margin: 0 0 6px; padding: 0 var(--krds-sp-1) 4px;
    border-bottom: 1px solid var(--krds-gray-10);
    font-size: 12px; font-weight: 700; color: var(--krds-text); }
.palette-group { margin: var(--krds-sp-3) 0 var(--krds-sp-1); padding: 0 var(--krds-sp-1);
    font-size: var(--krds-fs-caption); font-weight: 700; letter-spacing: .05em; color: var(--krds-text-weak); }
.palette-title + .palette-group { margin-top: 0; }
/* 세로 타일 2열 (수정요청 35): 아이콘을 라벨 위로 올려 폭을 132px 그대로 두면서 높이를 줄인다.
   캔버스는 현재 폭이 제약(여유 20px)이라, 팔레트를 넓히면 캔버스가 그만큼 작아진다 —
   그래서 가로 2열(192px) 대신 폭 비용이 0인 세로 타일을 쓴다. 실측 583px → 485px.
   타일이 56x45라 D28의 터치 기준(44x44)도 함께 충족한다(기존 1열 항목은 32px로 미달). */
.palette-group + div[role="group"] { display: grid; grid-template-columns: 1fr 1fr; gap: 3px; }
.palette-item { display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; width: 100%; padding: 6px 2px;
    background: var(--krds-surface); border: 1px solid var(--krds-border);
    border-radius: var(--krds-radius); cursor: pointer; text-align: center;
    font-family: inherit; font-size: var(--krds-fs-caption); line-height: 1.2; color: var(--krds-text); }
/* currentColor라 hover·고대비에서 글자와 같이 움직인다 */
.palette-ico { width: 16px; height: 16px; flex-shrink: 0;
    fill: none; stroke: currentColor; stroke-width: 1.6;
    stroke-linecap: round; stroke-linejoin: round; color: var(--krds-primary-50); }
.palette-item:hover .palette-ico { color: inherit; }
.palette-item:hover { border-color: var(--krds-primary-50); color: var(--krds-primary-text);
    background: var(--krds-primary-5); }
.palette-item:focus-visible { outline: none; box-shadow: var(--krds-focus); }

/* 우측: 속성 + 선택 삭제 + 문서 설정 */
.editor-props-col { width: 288px; flex-shrink: 0; display: flex; flex-direction: column;
    gap: var(--krds-sp-3); overflow-y: auto;
    /* 스크롤 상자를 위치 기준으로 — 안쪽 absolute(방향 칩의 숨은 radio)가 상자를 빠져나가 페이지를 늘리지 않게(16번 3-5) */
    position: relative; }
.editor-doc-settings { background: var(--krds-surface); border: 1px solid var(--krds-gray-10);
    border-radius: var(--krds-radius); padding: var(--krds-sp-4); }
.editor-doc-settings h3 { margin-bottom: var(--krds-sp-3); font-size: var(--krds-fs-body); } /* 없는 --krds-fs-md였다 — 실제로 보이던 16px 그대로(R4-6) */
.editor-doc-settings .field { display: flex; flex-direction: column; margin-bottom: var(--krds-sp-3); }
.editor-doc-settings .field:last-child { margin-bottom: 0; }
/* .field-label: 컨트롤 없는 제목(SPA 에디터의 고정 모듈 표시, D52-4) — 라벨과 같은 모양 */
.editor-doc-settings label, .editor-doc-settings .field-label { margin-bottom: var(--krds-sp-1); font-size: var(--krds-fs-sm); font-weight: 700; }
.editor-doc-settings select { padding: 7px var(--krds-sp-2); border: 1px solid var(--krds-border-strong);
    border-radius: var(--krds-radius); min-height: 40px; }

.editor-scenes { display: flex; gap: 4px; margin-bottom: var(--krds-sp-2); flex-wrap: wrap; }
.scene-tab { display: inline-flex; align-items: center; gap: var(--krds-sp-2);
    padding: 6px var(--krds-sp-3) 6px var(--krds-sp-4);
    border: 1px solid var(--krds-border); border-radius: var(--krds-radius) var(--krds-radius) 0 0;
    background: var(--krds-gray-5); cursor: pointer; font-size: var(--krds-fs-sm); }
.scene-tab.active { background: var(--krds-primary-50); color: var(--krds-on-primary); border-color: var(--krds-primary-50); }
.scene-tab.add { background: var(--krds-surface); color: var(--krds-primary-text); font-weight: 700;
    padding: 6px var(--krds-sp-4); }
/* 탭 이름: span으로 감싼 탭 안의 버튼이므로 배경/테두리 제거하고 색을 상속 */
.scene-name { background: none; border: none; padding: 0; min-height: 20px; cursor: pointer;
    font-family: inherit; font-size: inherit; color: inherit; }
.scene-name:focus-visible { outline: none; box-shadow: var(--krds-focus); border-radius: var(--krds-radius-sm); }
/* 삭제(X): 자리를 항상 차지해 탭 폭이 흔들리지 않게 하고, 활성 탭·hover에서만 드러낸다 */
.scene-close { display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px; border-radius: 50%; cursor: pointer;
    font-size: var(--krds-fs-caption); line-height: 1; opacity: 0; transition: opacity .12s, background .12s; }
.scene-tab:hover .scene-close, .scene-tab.active .scene-close { opacity: .75; }
.scene-close:hover { opacity: 1; background: var(--krds-critical); color: var(--krds-on-primary); }
.scene-close:focus-visible { opacity: 1; outline: none; box-shadow: var(--krds-focus); }
.wp-btn { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; border-radius: var(--krds-radius); text-align: center; }

.editor-body { display: flex; gap: var(--krds-sp-3); flex: 1; min-height: 0; }
.editor-canvas-wrap { flex: 1; background: var(--krds-gray-80); border-radius: var(--krds-radius);
    display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; }
/* flex-shrink:0 필수 — wrap이 flex라 캔버스가 flex 아이템이 되고, 인라인 width(1920px)가
   기본 flex-shrink:1로 찌그러진다. 높이(1080px)는 안 줄어 좁은 창에서 16:9가 0.6까지 깨졌다. */
.editor-canvas { flex-shrink: 0; background: var(--krds-canvas); transform-origin: center center;
    position: relative; box-shadow: 0 0 0 1px var(--krds-gray-70); }
.ed-widget { position: absolute; box-sizing: border-box; border: 1px dashed transparent; overflow: hidden; touch-action: none; }
.ed-widget:hover { border-color: var(--krds-primary-40); }
.ed-widget.selected { border: 2px solid var(--krds-primary-50); }
/* 인라인 삭제 배지: 선택된 위젯에만 노출.
   캔버스가 scale(--ed-scale)로 축소 렌더되므로 역-스케일로 실제 크기(20px)를 보존한다. */
/* 삭제 배지: KRDS 닫기 버튼처럼 원형 + 얇은 X. 단 테두리·X는 위험색을 유지한다 —
   KRDS의 close/delete 아이콘은 둘 다 X 모양이라 형태만으로는 '닫기'와 '삭제'가 구분되지 않고,
   이 배지는 확인 없이 즉시 삭제한다. 흰 배경 원이라 검은 캔버스·어두운 사진 위에서도 보인다.
   글리프(✕) 대신 SVG 선 — 폰트에 따라 굵기가 달라지지 않게(수정요청 38). */
.ed-widget-del { display: none; position: absolute; top: 2px; right: 2px;
    width: 20px; height: 20px; padding: 0; border-radius: 50%;
    border: 1.5px solid var(--krds-critical); background: var(--krds-surface); cursor: pointer;
    align-items: center; justify-content: center;
    box-shadow: var(--krds-shadow-1);
    transform: scale(calc(1 / var(--ed-scale, 1))); transform-origin: top right;
    z-index: 10; }
.ed-widget-del svg { width: 10px; height: 10px; fill: none; stroke: var(--krds-critical);
    stroke-width: 1.6; stroke-linecap: round; }
.ed-widget.selected .ed-widget-del { display: flex; }
/* 인라인 텍스트 편집 중: 상태를 테두리로 알리고, 편집 중 오삭제를 막기 위해 X 배지를 숨긴다 */
.ed-widget.editing { border: 2px dashed var(--krds-warning); }
.ed-widget.editing .ed-widget-del { display: none; }
.ed-widget [data-edit-text][contenteditable="true"] { outline: none; cursor: text; }
/* 누르기 직전에 위험을 한 번 더 알린다 — 확인 절차가 없으므로 */
.ed-widget-del:hover { background: var(--krds-critical); }
.ed-widget-del:hover svg { stroke: var(--krds-on-primary); }
/* 흰 배지가 되었으므로 흰 아웃라인은 보이지 않는다. 어떤 배경에서도 보이도록 흰+빨강 이중 링. */
.ed-widget-del:focus-visible { outline: none;
    box-shadow: 0 0 0 2px var(--krds-surface), 0 0 0 4px var(--krds-critical); }
.wp-text { width: 100%; height: 100%; display: flex; align-items: center; }
.wp-empty { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
    color: var(--krds-gray-30); background: var(--krds-canvas-empty); font-size: 20px; text-align: center; }
.editor-props { background: var(--krds-surface); border: 1px solid var(--krds-gray-10);
    border-radius: var(--krds-radius); padding: var(--krds-sp-4); }
.editor-props h3 { margin-bottom: var(--krds-sp-3); }
.editor-props label { display: block; margin-bottom: var(--krds-sp-3); font-size: var(--krds-fs-sm); font-weight: 700; }
/* 문서 설정 셀렉트도 같은 규칙 — 따로 두면 UA 기본(13.3px)으로 떨어진다 */
.editor-props input, .editor-props select, .editor-props textarea,
.editor-doc-settings select {
    display: block; width: 100%; margin-top: 3px; padding: 7px var(--krds-sp-2);
    border: 1px solid var(--krds-border-strong); border-radius: var(--krds-radius); font-size: var(--krds-fs-sm); }
.editor-props label.check { display: flex; align-items: center; gap: var(--krds-sp-2); }
.editor-props label.check input { width: auto; margin-top: 0; }
.pos-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: var(--krds-sp-2); }
.pos-grid .mini { margin-bottom: 0; }

/* ── 속성 패널 그룹화 (수정요청 37) ──
   선택한 위젯이 팔레트의 무엇인지 같은 아이콘·이름·그룹으로 잇는다.
   항목은 성격별로 fieldset/legend에 묶는다 — KRDS는 속성 패널 그룹화를 따로 규정하지 않지만,
   fieldset/legend로 그룹 목적을 전달하라는 조항(7343p)과 계층은 여백으로 구분(6709p)을 따른다. */
.props-head { display: flex; align-items: center; gap: var(--krds-sp-2);
    margin-bottom: var(--krds-sp-3); padding-bottom: var(--krds-sp-2);
    border-bottom: 1px solid var(--krds-gray-10); }
.props-head h3 { margin: 0; font-size: var(--krds-fs-sm); }
.props-ico { width: 18px; height: 18px; flex-shrink: 0;
    fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
    color: var(--krds-primary-50); }
.props-group { margin-left: auto; padding: 1px 7px; border-radius: var(--krds-radius-sm);
    background: var(--krds-primary-5); color: var(--krds-primary-text); font-size: var(--krds-fs-caption); font-weight: 700; }
.props-section { margin: 0 0 var(--krds-sp-3); padding: 0; border: none; }
.props-section > legend { padding: 0; margin-bottom: var(--krds-sp-1);
    font-size: var(--krds-fs-caption); font-weight: 700; letter-spacing: .05em; color: var(--krds-text-weak); }
.props-section > label:last-child { margin-bottom: 0; }
.props-note { margin: 0 0 var(--krds-sp-3); font-size: var(--krds-fs-caption); }
/* 위치·크기: 캔버스 드래그로 하는 게 보통이라 접어 둔다(details라 JS 불필요) */
.props-pos { border-top: 1px solid var(--krds-gray-10); padding-top: var(--krds-sp-2); }
.props-pos > summary { cursor: pointer; list-style: none; padding: 4px 2px; min-height: 24px;
    font-size: var(--krds-fs-caption); font-weight: 700; letter-spacing: .05em; color: var(--krds-text-weak); }
.props-pos > summary::-webkit-details-marker { display: none; }
.props-pos > summary::before { content: "▸"; margin-right: 5px; color: var(--krds-primary-50); }
.props-pos[open] > summary::before { content: "▾"; }
.props-pos > summary:focus-visible { outline: none; box-shadow: var(--krds-focus);
    border-radius: var(--krds-radius-sm); }
/* 버전 이력 다이얼로그 (수정요청 34) — 본문 흐름에 두면 버전이 쌓일수록
   고정 높이(100vh-64px)의 editor-body를 잠식해 팔레트·캔버스가 줄어든다. */
.modal-panel { width: min(560px, 92vw); }
.version-list { max-height: min(50vh, 420px); overflow-y: auto; margin-bottom: var(--krds-sp-3);
    border: 1px solid var(--krds-gray-10); border-radius: var(--krds-radius);
    padding: var(--krds-sp-2) var(--krds-sp-3); }
.version-row { display: flex; gap: var(--krds-sp-3); align-items: center; padding: 4px 0;
    font-size: var(--krds-fs-sm); }
.version-row + .version-row { border-top: 1px solid var(--krds-gray-5); }
/* 롤백 버튼·'현재' 배지를 오른쪽 끝으로 — bulk-spacer는 규칙이 없어 버튼이 일시 바로 뒤에 붙어 있었다(R6-10 검수, 옛 화면 공통) */
.version-row .bulk-spacer { flex: 1; }
.version-more { width: 100%; margin-top: var(--krds-sp-2); }

/* ── 반응형 (14번 #18: ≥1024 완전 지원, 900–1023 폼 1열, <900 과업 한정) ──
   파일 끝(터치 블록 바로 앞)에 둔다 — 에디터 등 뒤에 오는 같은 우선순위 규칙(.editor-shell display:flex)이 덮지 않게(16번 1-5) */
.menu-jump { display: none; }
.editor-narrow-notice { display: none; }
@media (max-width: 1023px) {
    .form, .deploy-wizard .wizard-cond { grid-template-columns: minmax(0, 1fr); }
    /* 에디터는 1024 이상 전용 — 캔버스 대신 안내 */
    .editor-narrow-notice { display: flex; flex-direction: column; align-items: flex-start; gap: var(--krds-sp-4);
        max-width: 560px; margin: var(--krds-sp-10) auto; padding: 0 var(--krds-sp-4); }
    /* 셸·main은 그대로 두고 작업 영역만 숨긴다 — h1·건너뛰기 대상(main#main-content)이 남는다 */
    .editor-main > .editor-toolbar, .editor-main > .editor-scenes, .editor-main > .editor-body { display: none; }
}
@media (max-width: 899px) {
    .layout { flex-direction: column; }
    /* 주메뉴는 본문 아래로(D38) — 본문이 첫 화면, 헤더 '☰ 메뉴'가 #main-nav로 이동 */
    .side-nav { order: 2; width: 100%; border-right: none; border-top: 1px solid var(--krds-gray-10);
        padding: var(--krds-sp-1) 0; }
    .main { order: 1; }
    .menu-jump { display: inline-flex; }
    .main { padding: var(--krds-sp-4); }
    .site-header-inner, .footer-inner { padding-left: var(--krds-sp-4); padding-right: var(--krds-sp-4); }
    /* 좁은 헤더: 한 줄(로고 · 로그아웃 · 전체 메뉴 — D92 전체 메뉴가 맨 오른쪽이라 줄이 넘으면 둘째 줄 왼쪽으로 떨어졌다).
       부가 정보(부제·사용자명)는 숨기고, 그래도 넘치면 서비스 이름을 말줄임(…)으로. 버튼 글자는 꺾이지 않게 */
    .site-header-inner { flex-wrap: nowrap; height: auto; min-height: 64px;
        padding-top: var(--krds-sp-2); padding-bottom: var(--krds-sp-2); }
    .brand-identifier, .brand-identifier > span { min-width: 0; }
    .brand-name { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .header-user { gap: var(--krds-sp-2); }
    .header-user .btn { white-space: nowrap; }
    .brand-sub, .header-user .user-name { display: none; }
}

/* 터치 최소 44×44px(KRDS p435, 14번 #17) — 이 블록 한 곳에서만. 밀도보다 정확도: 작은 버튼·표 행이 커지는 것을 허용.
   시각 크기를 바꾸면 안 되는 글자 링크는 padding + 같은 크기의 음수 margin으로 클릭 영역만 넓힌다(수정요청 46 방식).
   검수: docs/planning/scripts/control-size-audit.js 를 데스크톱·터치 에뮬레이션으로 두 번.
   파일 맨 끝에 둔다 — 같은 우선순위의 데스크톱 규칙(.scene-name, .login-links a 등)이 뒤에 오면 이 블록을 덮는다 */
/* ── 선택 상자(D86, DBDS 칩·상태·배지 1판 · Select) — 두 크기만: 입력 폼 44px·16px, 도구 줄·편집기 36px·14px.
   브라우저 기본 화살표 대신 같은 ∨(브라우저마다 달랐다). 앞의 규칙이 background 단축 속성을 쓰므로 맨 뒤에 둔다(16번 1-2) ── */
.form select, form.inline select, .editor-props select, .editor-doc-settings select {
    -webkit-appearance: none; appearance: none; padding-right: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235a606c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 18px; }
form.inline select, .editor-props select, .editor-doc-settings select, .form .template-module select, .form select.targets-dept {
    min-height: 36px; padding: 0 34px 0 10px; font-size: var(--krds-fs-sm); border: 1px solid var(--krds-border-strong);
    background-position: right 10px center; background-size: 16px; }
:is([data-theme="high-contrast"]) :is(.form select, form.inline select, .editor-props select, .editor-doc-settings select) { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d4d8de' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); }

@media (pointer: coarse) {
    .stepper-btn { width: 44px; height: 44px; font-size: 18px; }
    .number-stepper input[type=number] { min-height: 44px; }
    .btn, .btn-sm { min-height: 44px; }
    /* :root :is()로 (0,3,1) — 표 안 인라인 폼(form.inline input[type=text], 0,2,2 · 34px)을 이겨야 한다 */
    :root :is(input:not([type=checkbox]):not([type=radio]), select) { min-height: 44px; }
    .side-nav a, .nav-group-toggle, .brand-identifier { min-height: 44px; }
    .check, .check-hit { min-height: 44px; min-width: 44px; }
    .breadcrumb a { display: inline-block; min-width: 44px; text-align: center;
        padding-block: 12px; margin-block: -12px; padding-inline: 10px; margin-inline: -10px; }
    td a:not(.btn) { display: inline-block; padding-block: 11px; margin-block: -11px; }
    .footer-links a { display: inline-block; padding-block: 12px; margin-block: -12px; }
    .login-links a { padding-block: 14px; margin-block: -14px; }
    .scene-tab, .scene-name { min-height: 44px; }
    .scene-name { min-width: 44px; }
    /* D86 작은 선택 상자·D87 바닥글 접근성 줄도 누르는 영역 44px */
    form.inline select, .editor-props select, .editor-doc-settings select, .form .template-module select, .form select.targets-dept { min-height: 44px; }
    .footer-a11y a, .footer-a11y-btn { display: inline-block; padding-block: 12px; margin-block: -12px; }
}
