/* ══════════════════════════════════════════════════════════════
   frontdesigner.css — ActionFlow Front Designer 셸  v17
   (v15 대비: 닫히지 않은 규칙 하나를 걷어낸다. 그 뒤 규칙이 전부 죽어 있었다)

   ── v16 변경 ──
   1355 줄에 `.sv-hdr {` 가 선언 없이 열린 채로 닫히지 않았다. 파일 전체의
   중괄호 깊이가 1 로 끝난다. 크롬은 CSS 중첩(nesting)으로 해석하므로 오류를
   내지 않고, 그 뒤에 오는 규칙을 전부 `.sv-hdr` 안으로 빨아들인다.
   그래서 파일 뒷부분이 통째로 죽어 있었다 — 실측으로 확인했다:
     getComputedStyle(document.documentElement)
       .getPropertyValue('--af-css-ver')  ==  ''   (15 가 아니라 빈 문자열)

   죽어 있던 규칙 (전부 되살아난다)
     :root { --af-css-ver }        버전 표식. app.js 가 못 읽어 거짓 경고가 떴다
     .fw-body.pg                   폼 창 몸통의 세로 flex — 폼이 창을 못 채웠다
     .form.pg                      container-type: inline-size  ← 반응형의 근원(요구 3)이
                                   죽어 있어서 블록 안의 cqw 가 폼이 아니라 뷰포트를 봤다
     .form.pg .fnode               페이지 모드 블록의 테두리 0 / 배경 투명
     .form.pg .fnode:hover         마우스 올렸을 때 윤곽
     .form.pg .fkids               안쪽 상자 기본 세로 방향
     .icon.vp                      뷰포트 아이콘 크기
     .sv-list / .sv-row:hover / .sv-name / .sv-n / .sv-t / .sv-act / .sv-act button(:hover)
                                   서버 열기 대화상자 목록

   [삭제 목록]
     .sv-hdr { …   (1355 줄, 선언 없이 열린 채 안 닫힌 규칙) — 줄 자체를 없앤다.
                   선언이 하나도 없었으므로 지워도 표시가 달라지지 않는다.
                   ※ 1345 줄의 `.sv-hdr, .sv-row { display:grid … }` 는 그대로 남는다.
   [추가 목록]
     없음. 규칙을 새로 만들지 않았다. 되살아나는 것은 전부 원래 있던 규칙이다.

   [충돌 확인]
     · 되살아나는 `.form.pg .fkids { flex-direction: column }` 과 가로 행(row)의
       안쪽 상자가 부딪힌다. 행은 인라인으로 `flex-direction:row` 를 내고,
       인라인은 언제나 CSS 를 이기므로 결과는 안 바뀐다(실측 확인).
       배치를 인라인이 갖는 v05 의 결정이 여기서 값을 한다.
     · 중복 클래스 정의 0. `.sv-hdr` 는 1345 줄 한 곳에만 남는다.
     · 4개 CSS 전체 @media 0건 / @container 0건 / container-type 선언 1건 (그대로)

   ※ --af-css-ver 를 16 으로 올렸다. page.js 의 CSS_EXPECT 도 16 이다.

   (v15: 배치 값을 CSS 에서 뺐다. 배치는 인라인 스타일(page.js)이 책임진다)

   ── v15 변경 ──
   [삭제 목록]  (전부 인라인으로 옮겨 갔다. 같은 값이 두 곳에 있으면 안 된다)
     .form.pg { padding / border / background-image }   → PAGE.formStyle()
     .form.pg .fnode > .fkids                            → PAGE.kidsStyle()
     .form.pg .fnode > .fkids.empty                      → PAGE.kidsStyle()
     .pgh                                                → nodeHTML 의 pghCss
     .pgh::after / .pgh:hover::after                     → nodeHTML 의 gripCss
     .form.pg .fnode.sel > .pgh::after
     .form.pg .fnode.primary > .pgh::after
   [추가 목록]
     :root { --af-css-ver }   CSS 버전 표식. app.js 가 기동 시 읽어 캐시 여부를 알린다.
   ※ 남는 .form.pg 규칙은 container-type 하나뿐이다(반응형의 근원이라 CSS 에 있어야 한다).
     .form.pg .fnode / :hover / .fkids 는 '표시' 라 CSS 에 남긴다(배치에 영향 없음).

   ── v14 변경 ──
   [삭제 목록]
     .pgh { bottom: -5px; height: 10px }   → 값만 교체(-7px / 14px). 규칙은 그대로 남는다.
   [추가 목록]
     .form.pg .fnode > .fkids          안쪽 상자가 부모 높이를 밀어올리지 못하게 한다
     .form.pg .fnode > .fkids.empty    빈 드롭 상자의 46px 최소 높이를 푼다
     .form.pg .fnode.sel > .pgh::after 선택 중이면 손잡이를 진하게
   ※ .fkids / .fkids.empty 기존 규칙은 그대로 두고 .form.pg 안에서만 덮는다.
     페이지 모드가 아닐 때(자유배치 비교용)는 예전 값 그대로 동작한다.

   ── v13 변경 ──
   [삭제 목록]  (셀렉터 5개 전부 제거. 이 파일에 .page-frame 은 하나도 남지 않는다)
     .page-frame
     .page-frame > .form
     .page-frame .fnode
     .page-frame .fnode:hover
     .page-frame .fkids
   [추가 목록]  (위 5개를 .form.pg 기준으로 옮긴 것 + 세로 채움 1개)
     .form.pg
     .form.pg .fnode
     .form.pg .fnode:hover
     .form.pg .fkids
     .fw-body.pg          폼이 창의 남는 높이를 채우게 하는 세로 flex
     ※ '.page-frame > .form' 은 .form.pg 자신에 흡수되어 하나 줄었다.
     ※ .fw-body.pg 는 기존 .fw-body 규칙(padding/flex/min-height/overflow)에
       display 두 줄만 더하는 것이라 선언 충돌이 없다(중복 0).
   ※ 패치 전 재확인: 4개 CSS 전체에 .pg / .form.pg 는 0건, @media·@container 0건.
     container-type 은 이 파일 .form.pg 한 곳뿐이다(중복 0).

   ── v12 변경 ──
   [삭제 목록]
     .page-frame { margin: 0 auto }              가운데 정렬. 폭 제한이 없어져 의미가 없다.
     .page-frame { transition: max-width .18s }  바뀌는 것이 프레임이 아니라 창이라 불필요.
     ※ 위 두 선언만 제거하고 .page-frame 규칙 자체는 남는다(container-type 이 여기 있다).
   [추가 목록]
     없음
   ※ v11 에서 확인한 대로 4개 CSS 전체에 @media / @container / container-type 은
     이 파일의 .page-frame 한 곳뿐이다. 이번에도 새 셀렉터를 만들지 않으므로 중복 0.

   ── v11 변경 (패치 전 4개 CSS 파일 전체 grep 결과) ──
   [삭제 목록]  없음
     · @media        : 전체 0건 (frontdesigner / fd-classic / af-dock / af-theme)
     · @container    : 전체 0건
     · container-type: 전체 0건
     · page-frame / pgh / vp : 전체 0건
     → 새로 넣는 셀렉터와 겹치는 기존 정의가 하나도 없다. 순수 추가다.

   [추가 목록]
     .page-frame                  반응형의 근원. container-type 은 여기 하나뿐이다.
     .page-frame > .form          페이지 캔버스(패딩·격자·테두리 제거)
     .page-frame .fnode           흐름형 블록(테두리 없음 — 내보내기와 폭이 어긋나지 않게)
     .page-frame .fnode:hover     윤곽선으로만 표시(outline 은 배치에 영향이 없다)
     .page-frame .fkids           컨테이너 안쪽도 같은 흐름형
     .pgh                         아래 가장자리 높이 손잡이
     .icon.vp                     툴바 뷰포트 버튼

   ── 왜 테두리를 지우는가 ──
   .fnode 의 1px 테두리는 border-box 라 바깥 크기는 그대로지만 안쪽 폭을 2px 줄인다.
   에디터에만 있고 내보낸 문서에는 없는 값이라, 그대로 두면 같은 블록의 안쪽 폭이
   에디터와 결과물에서 서로 다르다(요구 5 — 구조 불변). outline 은 배치에 관여하지
   않으므로 선택·호버 표시는 전부 outline 으로 낸다.

   색은 af-theme.css + fd-classic.css 의 var(--...) 참조만. 값 정의 금지.
   로드 순서: af-theme.css → fd-classic.css → frontdesigner.css

   [삭제 목록] (v01 대비)
     .body(3열 그리드) .left .right .resizer .panel-title
     .pal-search .pal .pal-cat .pal-item
     .canvas-wrap .stage-frame .stage .stage-empty
     .props .prop-empty  .statusbar
     ※ v01 파일 전체를 대체하므로 위 셀렉터는 이 파일에 존재하지 않는다.

   [추가 목록]
     레이아웃 : .app .menubar .toolbar .tb-sep .body .dock-col .splitter .hsplitter
     메뉴     : .menu .title .dropdown .mi .menu-sep .submenu .has-sub .check .sc
                .mb-flex .badge
     도크     : .dock .dock-title .dock-btns .dock-btn .dock-body .filter
     위젯박스 : .wbox .wcat .wcat-arrow .wlist .witem .wicon
     MDI/폼   : .mdi .formwin .fw-title .fw-tx .fw-btns .fw-btn .fw-body
                .form .fw-grip  .fnode .fnode.sel .fsel-h
     인스펙터 : .tree .thead .th .trow .tcell .texp .ticon
     속성편집 : .pe-head .ptable .pgroup .parrow .prow .prow.hi .pname .pval
                .pval input .pval select .pval .chk
     리소스   : .res-tools .res-panes .res-list .res-prev .res-root
     탭바     : .tabbar .tab .tab.active
     공통     : button .primary .flex .icon .overlay .modal .modal-title
                .modal-content .modal-actions .empty
     v03 추가 : .ico-img
                .modal.wide .is-help .iconset .is-cat .is-row .is-prev
                .is-name .is-name em .is-act
     v10 [추가] : .fnode.free .fnode.primary .fkids.free .fkids.empty .fmarquee .trow.primary
                  .fh 및 .fh-nw~.fh-w (크기 조절 손잡이 8방향)
     v09 [수정] : .formwin 을 MDI 창으로 — 절대 위치, 활성/비활성 구분,
                  최소화는 좌하단 정렬, 최대화는 작업영역 전체
                  [삭제] .formwin(문서 흐름 배치) .formwin.mini(고정 좌표)
     v08 [추가] : .pal-tabs .pal-tab .pal-search .pal-content .pal-chip
                  .pal-chip .dot .pal-chip .star .pal-empty
                  ※ 제너레이터(runner) generator.css 의 같은 이름들과 의도적으로
                    동일한 구조다. 나중에 공용 CSS 로 합칠 때 그대로 옮기면 된다.
     v07 [삭제] : 도크 관련 일체를 af-dock.css 로 넘김
                  .body #dockWidgetBox #splitL #mdi(그리드칸) #splitR #rightCol
                  .splitter .hsplitter .dock-col
                  .dock .dock.hidden .dock.floating .dock.floating > .dock-title
                  .dock-title .dock-btns .dock-btn .dock-body
                  ※ 같은 이름을 여기서 다시 정의하지 말 것(프레임워크와 충돌)
     v07 [추가] : .af-dock .filter(도크 내부용으로 유지)
     v06 추가 : .mdi-empty .me-box .me-tx .me-act  .i18n-en
                .formwin.mini(작업영역 좌하단 축소) — [수정] v05 의 제자리 접기 대체
     v05 추가 : .langbtn  .mtx  .dock.floating(강조 보강)  .formwin.maxi(높이 포함)
     v04 추가 : .dock.floating  .form.nogrid  .fkids .fdrop .fnode.over
                .fnode.pick .ftab .fbuddy  .formwin.mini .formwin.maxi
                .form.mode-signals .form.mode-buddy .form.mode-taborder
                .pane .pane-list .pane-filter .hint .rrow .rdel
                .codetabs .ctab .code  .dlg-row  .prow.dyn
   ══════════════════════════════════════════════════════════════ */

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  background: var(--window);
  color: var(--text);
  font: 12px/1.45 "Malgun Gothic", "맑은 고딕", "Segoe UI", system-ui, sans-serif;
  overflow: hidden;
}

.app {
  height: 100%;
  display: grid;
  grid-template-rows: auto auto 1fr;
}

.flex { flex: 1; }

.empty {
  padding: 20px 12px;
  text-align: center;
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.9;
}

/* ── 메뉴바 ────────────────────────────────────────────────── */
.menubar {
  display: flex;
  align-items: stretch;
  background: var(--window);
  border-bottom: 1px solid var(--line);
  user-select: none;
  position: relative;
  z-index: 60;
}

.menu { position: relative; }

.menu > .title {
  padding: 5px 11px;
  cursor: default;
  white-space: nowrap;
}

.menu.open > .title { background: var(--sel); color: var(--sel-tx); }

.dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 250px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 3px 3px 10px rgba(0, 0, 0, .28);
  padding: 3px 0;
  z-index: 70;
}

.menu.open > .dropdown { display: block; }

.mi {
  padding: 5px 14px 5px 26px;
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
  cursor: default;
  position: relative;
}

.mi:hover { background: var(--sel); color: var(--sel-tx); }

.mi.disabled { color: var(--text-dim); pointer-events: none; }

.menu-sep { height: 1px; margin: 4px 6px; background: var(--line); }

.mi .sc { margin-left: auto; padding-left: 24px; color: var(--text-dim); }

.mi .check { position: absolute; left: 9px; }

.mi:hover .sc { color: var(--sel-tx); }

.has-sub::after { content: "▸"; margin-left: auto; padding-left: 20px; }

.submenu {
  display: none;
  position: absolute;
  top: -3px;
  left: 100%;
  min-width: 210px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 3px 3px 10px rgba(0, 0, 0, .28);
  padding: 3px 0;
  color: var(--text);   /* [통합] 아래 중복 규칙을 여기로 합침 */
}

/* 하위 메뉴는 부모의 hover 글자색(흰색)을 물려받으면 안 된다.
   classic 테마에서 밝은 배경 위에 흰 글자가 찍혀 글자가 사라졌다. */
.submenu .mi { color: var(--text); }

.submenu .mi:hover { background: var(--sel); color: var(--sel-tx); }

.submenu .mi .sc { color: var(--text-dim); }

.has-sub:hover > .submenu { display: block; }

.mb-flex { flex: 1; }

.badge {
  align-self: center;
  margin-right: 8px;
  padding: 1px 9px;
  border: 1px solid var(--line);
  border-radius: 9px;
  font-size: 11px;
  color: var(--text-dim);
  cursor: default;
}

/* ── 툴바 ──────────────────────────────────────────────────── */
.toolbar {
  display: flex;
  align-items: center;
  gap: 1px;
  padding: 3px 6px;
  background: var(--toolbar);
  border-bottom: 1px solid var(--line);
  user-select: none;
}

.tb-sep {
  width: 1px;
  height: 20px;
  margin: 0 5px;
  background: var(--line);
}

.icon {
  width: 26px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: default;
  color: var(--text);
}

.icon:hover { background: var(--btn-hover); border-color: var(--line); }

.icon.on { background: var(--btn-hover); border-color: var(--line); }

.icon.disabled { opacity: .4; pointer-events: none; }

.icon .ico-img { width: 17px; height: 17px; }

button {
  background: var(--btn);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 4px 12px;
  font: inherit;
  cursor: pointer;
}

button:hover { background: var(--btn-hover); }

button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }

.filter { padding: 4px; }

.filter input,
.pval input,
.pval select {
  width: 100%;
  background: var(--base);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 3px 6px;
  font: inherit;
}

.filter input:focus,
.pval input:focus,
.pval select:focus { outline: 1px solid var(--accent); outline-offset: -2px; }

/* ── Widget Box ────────────────────────────────────────────── */
.wbox {
  flex: 1;
  overflow: auto;
  background: var(--base);
  border-top: 1px solid var(--line);
}

.wcat {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: 4px 8px;
  background: var(--group);
  border-bottom: 1px solid var(--group-line);
  font-size: 11.5px;
  font-weight: 600;
  cursor: default;
}

.wcat-arrow { position: absolute; left: 6px; font-size: 9px; color: var(--text-dim); }

.wlist { display: block; }

.wlist.collapsed { display: none; }

.witem {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 8px 3px 10px;
  cursor: grab;
  white-space: nowrap;
}

.witem:hover { background: var(--btn-hover); }

.witem.sel { background: var(--sel); color: var(--sel-tx); }

.wicon {
  width: 16px;
  height: 16px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
}

.wicon .ico-img { width: 16px; height: 16px; }

/* ── MDI 작업영역 / 폼 창 ──────────────────────────────────── */
.mdi {
  /* [추가] v07: af-center 안에서 세로로 꽉 차야 한다. 이게 없으면 폼 창을
     최소화했을 때(absolute) mdi 높이가 0 으로 접혀 bottom:8px 이 화면 위쪽을
     가리키고, 축소된 창이 툴바 뒤로 숨어 클릭이 안 먹는다. */
  flex: 1;
  position: relative;   /* 최소화한 폼 창의 기준 좌표계 */
  background: var(--mdi);
  border: 1px solid var(--line);
  overflow: auto;
  padding: 8px;
  min-width: 0;
}

/* [삭제] v08 까지: 문서 흐름에 놓인 단일 창(width 고정)
   [추가] v09: 문서마다 창 하나. 절대 위치라 계단식으로 겹쳐 뜬다. */
.formwin {
  position: absolute;
  width: 668px;
  /* [삭제] max-width: calc(100% - 16px)
     — 이 제한 때문에 폼을 넓혀도 창이 작업영역 폭에서 잘려 가로 스크롤이
       생기지 않았다. 이제 넘치면 MDI 작업영역이 가로로 스크롤된다. */
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 2px 2px 10px rgba(0, 0, 0, .4);
  display: flex;
  flex-direction: column;
  z-index: 1;
}

/* z-index 는 app.js 가 창마다 인라인으로 준다(활성 순서 = 겹침 순서). */
.formwin.active { box-shadow: 3px 3px 16px rgba(0, 0, 0, .5); }

/* 활성이 아닌 창은 제목줄을 죽여 어느 것이 편집 중인지 바로 보이게 */
.formwin:not(.active) > .fw-title {
  background: var(--group);
  color: var(--text-dim);
}

.formwin:not(.active) .fw-btn {
  background: transparent;
  border-color: var(--line);
  color: var(--text-dim);
}

.fw-title {
  display: flex;
  align-items: center;
  padding: 2px 3px 2px 8px;
  background: linear-gradient(to bottom, var(--titlebar-2), var(--titlebar));
  color: var(--titlebar-tx);
  font-size: 11.5px;
  cursor: default;
}

.fw-tx { flex: 1; text-align: center; font-weight: 600; }

.fw-btns { display: flex; gap: 2px; }

.fw-btn {
  width: 16px;
  height: 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .22);
  border: 1px solid rgba(255, 255, 255, .35);
  font-size: 9px;
  line-height: 1;
  cursor: default;
}

.fw-btn:hover { background: rgba(255, 255, 255, .4); }

/* 폼이 창보다 크면 창 안에서 스크롤한다(창 밖으로 나가지 않게) */
.fw-body {
  padding: 6px;
  flex: 1;
  min-height: 0;
  overflow: auto;
}

/* 폼 경계 밖으로는 위젯이 나가지 않는다. 다만 잘라내기만 하면 늘어난 부분을
   볼 방법이 없으므로 폼 자체가 스크롤된다(auto).
   패딩 10px 덕분에 좌상단 크기 손잡이는 잘리지 않는다. */
.form {
  overflow: auto;
  position: relative;
  min-height: 380px;
  padding: 10px;
  background-color: var(--form);
  background-image: radial-gradient(var(--form-dot) 1px, transparent 1px);
  background-size: 10px 10px;
  background-position: 4px 4px;
  border: 1px solid var(--line);
}

.fnode {
  position: relative;
  margin: 6px 0;
  padding: 5px 8px;
  background: var(--base);
  border: 1px solid var(--line);
  cursor: default;
  min-height: 24px;
}

/* 여러 개 고르면 전부 점선, 그중 대표(속성 편집기가 보는 것)는 실선 */
.fnode.sel { outline: 1px dashed var(--handle); outline-offset: 1px; }

.fnode.primary { outline: 2px solid var(--handle); outline-offset: 1px; }

.fnode.over { outline: 2px solid var(--accent); outline-offset: 1px; }

.fnode.pick { outline: 2px dashed var(--warn); outline-offset: 1px; }

.fsel-h {
  position: absolute;
  width: 6px;
  height: 6px;
  background: var(--handle);
}

.fw-grip {
  height: 12px;
  cursor: nwse-resize;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 3px;
  color: var(--text-dim);
  font-size: 10px;
}

/* ── Object Inspector (트리) ───────────────────────────────── */
.tree { flex: 1; overflow: auto; background: var(--base); }

.thead {
  display: flex;
  position: sticky;
  top: 0;
  background: var(--group);
  border-bottom: 1px solid var(--group-line);
  font-size: 11.5px;
  font-weight: 600;
  z-index: 2;
}

.th { padding: 3px 8px; border-right: 1px solid var(--group-line); }

.th:last-child { border-right: 0; }

.trow { display: flex; cursor: default; }

.trow:hover { background: var(--btn-hover); }

.trow.sel { background: var(--sel); color: var(--sel-tx); }

.tcell {
  padding: 2px 8px;
  display: flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.texp { width: 11px; flex: none; font-size: 9px; color: var(--text-dim); }

.trow.sel .texp { color: var(--sel-tx); }

.ticon { width: 14px; flex: none; display: inline-flex; color: var(--accent); }

.ticon .ico-img { width: 13px; height: 13px; }

/* ── Property Editor ───────────────────────────────────────── */
.pe-head {
  padding: 3px 8px;
  background: var(--base);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-size: 11.5px;
}

.ptable { flex: 1; overflow: auto; background: var(--base); }

.pgroup {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  background: var(--group);
  border-bottom: 1px solid var(--group-line);
  font-weight: 600;
  cursor: default;
}

.parrow { font-size: 9px; color: var(--text-dim); }

.prow {
  display: grid;
  grid-template-columns: 46% 54%;
  border-bottom: 1px solid var(--grid);
  cursor: default;
}

.prow.hi { background: var(--prop-hi); }

.pname {
  padding: 2px 8px 2px 20px;
  border-right: 1px solid var(--grid);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.prow.bold .pname { font-weight: 700; }

.pval { padding: 1px 4px; display: flex; align-items: center; min-width: 0; }

.pval .chk { width: 13px; height: 13px; }

/* ── Resource Browser ──────────────────────────────────────── */
.res-tools {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 5px;
  border-bottom: 1px solid var(--line);
}

.res-panes {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  min-height: 0;
}

.res-list,
.res-prev {
  background: var(--base);
  border: 1px solid var(--line);
  overflow: auto;
  min-height: 0;
}

.res-root { padding: 4px 8px; }

/* ── 하단 탭바 ─────────────────────────────────────────────── */
.tabbar {
  display: flex;
  gap: 1px;
  padding: 2px 3px 0;
  background: var(--window);
  border-top: 1px solid var(--line);
}

.tab {
  padding: 3px 12px;
  background: var(--dock-title);
  border: 1px solid var(--line);
  border-bottom: 0;
  font-size: 11.5px;
  cursor: default;
}

.tab.active { background: var(--panel); font-weight: 600; }

/* ── 모달 ──────────────────────────────────────────────────── */
.overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .35);
  /* 폼 창이 아무리 많아도(창마다 z 를 하나씩 쓴다) 대화상자가 뒤로 숨지 않도록
     충분히 높게 둔다. 전에는 100 이라 창이 100개를 넘으면 가려졌다. */
  z-index: 9000;
  align-items: center;
  justify-content: center;
}

.overlay.open { display: flex; }

.modal {
  width: min(560px, 92vw);
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .4);
}

.modal-title {
  padding: 8px 14px;
  background: var(--dock-title);
  border-bottom: 1px solid var(--line);
  font-weight: 700;
}

.modal-content { padding: 14px; max-height: 60vh; overflow: auto; }

.modal-actions {
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* ── 아이콘 이미지 ─────────────────────────────────────────── */
.ico-img {
  display: block;
  image-rendering: -webkit-optimize-contrast;
  user-select: none;
  pointer-events: none;
}

.icon.disabled .ico-img { opacity: .45; }

/* ── 아이콘 설정 대화상자 ──────────────────────────────────── */
.modal.wide { width: min(720px, 94vw); }

.is-help {
  margin-bottom: 10px;
  padding: 8px 10px;
  background: var(--base);
  border: 1px solid var(--line);
  color: var(--text-dim);
  line-height: 1.8;
}

.iconset {
  max-height: 46vh;
  overflow: auto;
  background: var(--base);
  border: 1px solid var(--line);
}

.is-cat {
  position: sticky;
  top: 0;
  padding: 4px 10px;
  background: var(--group);
  border-bottom: 1px solid var(--group-line);
  font-weight: 700;
  z-index: 1;
}

.is-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 10px;
  border-bottom: 1px solid var(--grid);
}

.is-row:hover { background: var(--btn-hover); }

.is-prev {
  width: 24px;
  height: 24px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--panel);
  border: 1px solid var(--line);
}

.is-name { flex: 1; min-width: 0; }

.is-name em {
  display: block;
  font-style: normal;
  font-size: 11px;
  color: var(--text-dim);
}

.is-act { display: flex; gap: 4px; flex: none; }

.is-act button { padding: 2px 9px; font-size: 11.5px; }

.is-act button:disabled { opacity: .45; cursor: default; }

/* ── v04 : 폼 캔버스 보강 ──────────────────────────────────── */
.form.nogrid { background-image: none; }

.form.mode-signals .fnode,
.form.mode-buddy .fnode,
.form.mode-taborder .fnode { cursor: crosshair; }

.fkids {
  width: 100%;
  /* 컨테이너의 남은 높이를 채운다. 안쪽 세로 여백이 늘어날 자리를 만든다. */
  flex: 1;
  min-height: 0;
}

.fdrop {
  padding: 6px 0;
  color: var(--text-dim);
  font-size: 11px;
}

.ftab {
  position: absolute;
  top: -1px;
  left: -1px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  background: var(--warn);
  color: #fff;
  font-size: 10px;
  line-height: 15px;
  text-align: center;
  z-index: 3;
}

.fbuddy {
  position: absolute;
  top: -1px;
  right: -1px;
  width: 15px;
  height: 15px;
  background: var(--ok);
  color: #fff;
  font-size: 10px;
  line-height: 15px;
  text-align: center;
  z-index: 3;
}

/* ── v04 : 폼 창 상태 ─────────────────────────────────────── */
/* [삭제] v05: .formwin.mini 는 폭을 그대로 둔 채 본문만 감췄다(= 제자리 접기).
   [추가] v06: 실제 창처럼 작업영역 왼쪽 아래로 줄어든다. */
.formwin.mini {
  top: auto !important;
  bottom: 8px;
  width: 280px !important;
  height: auto !important;   /* [수정] v17: 인라인 height({w.h}px)를 이겨 최소화 시 제목줄만 남게(본문 display:none 이므로 접힘) */
}

.formwin.mini .fw-body,
.formwin.mini .fw-grip { display: none; }

.formwin.mini .fw-tx {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.formwin.maxi {
  left: 0 !important;
  top: 0 !important;
  width: 100% !important;
  height: 100%;
}

.formwin.maxi .fw-body { flex: 1; min-height: 0; overflow: auto; }

.formwin.maxi .form { min-height: 100%; }

/* 접었을 때 제목줄만 남는다는 걸 보이게 */
.formwin.mini > .fw-title { opacity: .85; }

/* ── v04 : 하단 탭 패널 ───────────────────────────────────── */
.pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.pane-list {
  flex: 1;
  overflow: auto;
  background: var(--base);
  border: 1px solid var(--line);
  margin: 4px;
}

.pane-filter {
  width: 150px;
  background: var(--base);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 3px 6px;
  font: inherit;
}

.hint {
  color: var(--text-dim);
  font-size: 11px;
  padding-left: 4px;
}

.rrow {
  display: flex;
  align-items: center;
  padding: 2px 8px;
  border-bottom: 1px solid var(--grid);
}

.rdel {
  margin-left: auto;
  padding: 0 4px;
  color: var(--err);
  cursor: default;
}

.rdel:hover { background: var(--err); color: #fff; }

.pane-list .tcell input,
.res-list .tcell input {
  width: 100%;
  background: transparent;
  color: var(--text);
  border: 1px solid transparent;
  padding: 1px 3px;
  font: inherit;
}

.pane-list .tcell input:focus {
  background: var(--base);
  border-color: var(--accent);
  outline: none;
}

/* ── v04 : 코드 보기 ──────────────────────────────────────── */
.codetabs { display: flex; gap: 1px; margin-bottom: -1px; }

.ctab {
  padding: 4px 14px;
  background: var(--dock-title);
  border: 1px solid var(--line);
  border-bottom: 0;
  cursor: default;
}

.ctab.active { background: var(--base); font-weight: 700; }

.code {
  max-height: 48vh;
  overflow: auto;
  margin: 0;
  padding: 10px;
  background: var(--base);
  border: 1px solid var(--line);
  font: 11.5px/1.6 "Consolas", "D2Coding", monospace;
  white-space: pre;
}

/* ── v04 : 대화상자 폼 ────────────────────────────────────── */
.dlg-row {
  display: grid;
  grid-template-columns: 130px 1fr;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
}

.dlg-row > label { color: var(--text-dim); }

.dlg-row input[type="text"],
.dlg-row input[type="number"],
.dlg-row select {
  width: 100%;
  background: var(--base);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 4px 7px;
  font: inherit;
}

.prow.dyn .pname { font-style: italic; }

/* ── v05 : 표시 언어 버튼 ─────────────────────────────────── */
.langbtn {
  align-self: center;
  margin-right: 6px;
  padding: 1px 10px;
  min-width: 62px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--btn);
  font-size: 11px;
  cursor: pointer;
  user-select: none;
}

.langbtn:hover { background: var(--btn-hover); border-color: var(--accent); }

/* 메뉴 항목의 라벨 (체크표시·단축키와 분리) */
.mtx { white-space: nowrap; }

/* ── v06 : 빈 작업영역 (폼을 닫았을 때) ───────────────────── */
.mdi-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.me-box {
  padding: 22px 28px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .35);
  text-align: center;
}

.me-tx { line-height: 1.9; color: var(--text); }

.me-act {
  margin-top: 14px;
  display: flex;
  gap: 8px;
  justify-content: center;
}

/* ── v06 : 병기 모드의 영문 줄 ────────────────────────────── */
.i18n-en {
  color: var(--text-dim);
  font-size: .92em;
}

/* ── v08 : 빠른 접근 팔레트 (Quick Access Palette) ────────────
   제너레이터의 팔레트와 같은 구성: 카테고리 탭 한 줄 + 가로 스크롤되는 칩 한 줄. */
.pal-tabs {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: none;
  padding: 0 4px;
  background: var(--dock-title);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  overflow-y: hidden;
}

.pal-tabs::-webkit-scrollbar { height: 6px; }

.pal-tab {
  padding: 4px 11px;
  font-size: 11.5px;
  white-space: nowrap;
  cursor: default;
  color: var(--text-dim);
  border-bottom: 2px solid transparent;
}

.pal-tab:hover { color: var(--text); }

.pal-tab.active {
  color: var(--text);
  background: var(--panel);
  border-bottom-color: var(--accent);
  font-weight: 700;
}

.pal-search {
  flex: none;
  width: 150px;
  margin: 3px 2px;
  background: var(--base);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 2px 7px;
  font: inherit;
  font-size: 11.5px;
}

.pal-search:focus { outline: 1px solid var(--accent); outline-offset: -2px; }

.pal-content {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 8px;
  min-height: 40px;
  background: var(--panel);
  overflow-x: auto;
  overflow-y: hidden;
}

.pal-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  padding: 4px 10px;
  background: var(--btn);
  border: 1px solid var(--line);
  border-radius: 4px;
  font-size: 11.5px;
  white-space: nowrap;
  cursor: grab;
}

.pal-chip:hover { border-color: var(--accent); background: var(--btn-hover); }

.pal-chip .dot {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex: none;
}

.pal-chip .ico-img { width: 15px; height: 15px; }

.pal-chip .star { color: var(--warn); font-size: 10px; }

.pal-empty {
  color: var(--text-dim);
  font-size: 11.5px;
  padding: 4px 6px;
}

/* ── v10 : 자유 배치 / 다중 선택 ──────────────────────────── */
/* [삭제] .fnode.free { margin: 0 !important; }
   — 사용자가 지정한 바깥 여백(margin)까지 눌러버려서 값이 안 먹었다.
     기본값이 0 이므로 이 규칙 없이도 자유 배치는 그대로다. */

.fkids.free { position: relative; }

/* 비어 있는 컨테이너도 떨어뜨릴 자리를 보여준다 */
.fkids.empty {
  min-height: 46px;
  border: 1px dashed var(--line);
  display: block;
}

.fkids.empty:hover { border-color: var(--accent); }

/* 고무줄 선택 상자 */
.fmarquee {
  position: absolute;
  z-index: 6;
  border: 1px dashed var(--handle);
  background: rgba(56, 116, 216, .14);
  pointer-events: none;
}

.trow.primary { font-weight: 700; }

/* ── v12 : 크기 조절 손잡이 ───────────────────────────────── */
.fh {
  position: absolute;
  width: 7px;
  height: 7px;
  background: var(--handle);
  border: 1px solid #fff;
  z-index: 5;
}

.fh-nw { left: -4px;  top: -4px;    cursor: nwse-resize; }
.fh-n  { left: 50%;   top: -4px;    margin-left: -4px; cursor: ns-resize; }
.fh-ne { right: -4px; top: -4px;    cursor: nesw-resize; }
.fh-e  { right: -4px; top: 50%;     margin-top: -4px;  cursor: ew-resize; }
.fh-se { right: -4px; bottom: -4px; cursor: nwse-resize; }
.fh-s  { left: 50%;   bottom: -4px; margin-left: -4px; cursor: ns-resize; }
.fh-sw { left: -4px;  bottom: -4px; cursor: nesw-resize; }
.fh-w  { left: -4px;  top: 50%;     margin-top: -4px;  cursor: ew-resize; }

/* ── v16 : 스크롤바를 눈에 띄게 ─────────────────────────────── */
.mdi::-webkit-scrollbar,
.fw-body::-webkit-scrollbar,
.form::-webkit-scrollbar { width: 12px; height: 12px; }

.mdi::-webkit-scrollbar-track,
.fw-body::-webkit-scrollbar-track,
.form::-webkit-scrollbar-track { background: var(--group); }

.mdi::-webkit-scrollbar-thumb,
.fw-body::-webkit-scrollbar-thumb,
.form::-webkit-scrollbar-thumb {
  background: var(--line);
  border: 2px solid var(--group);
  border-radius: 6px;
}

.mdi::-webkit-scrollbar-thumb:hover,
.fw-body::-webkit-scrollbar-thumb:hover,
.form::-webkit-scrollbar-thumb:hover { background: var(--accent); }

/* ── v17 : 위젯 내용은 상자 밖으로 넘치지 않는다 ───────────── */
.fbody {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}

/* 채움형 컨트롤(입력창·표·목록…) 안에서 여러 줄이 세로로 쌓일 때 */
.fbody > div[style*="flex-direction:column"] { flex-direction: column; }

.fbody > * { max-width: 100%; }

.ftrunc {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

/* 폼 안에서 글자 직접 고치기 */
.finline {
  position: absolute;
  z-index: 7;
  padding: 3px 6px;
  border: 2px solid var(--accent);
  background: #fff;
  color: #111;
  font: inherit;
  outline: none;
}

/* ── v20 : 목록형 · 여러 줄 속성 입력칸 ───────────────────── */
.pval .plist {
  flex: 1;
  min-width: 0;
  cursor: default;
  background: var(--base);
}

.pval .pmore {
  flex: none;
  margin-left: 3px;
  padding: 1px 7px;
  font: inherit;
  line-height: 1.2;
  background: var(--btn);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}

.pval .pmore:hover { background: var(--btn-hover); border-color: var(--accent); }

.pval textarea {
  width: 100%;
  resize: vertical;
  background: var(--base);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 3px 6px;
  font: inherit;
}

.pval textarea:focus { outline: 1px solid var(--accent); outline-offset: -2px; }

/* 여러 줄 칸이 들어가면 행 높이를 늘린다 */
.prow:has(textarea) { align-items: start; }

/* ── v28 : 데이터(행) 편집기 ──────────────────────────────── */
.re-grid { max-height: 46vh; overflow: auto; }

.re-head,
.re-row {
  display: grid;
  grid-template-columns: var(--re-cols, 1fr 1fr 86px);
  gap: 4px;
  align-items: center;
  padding: 2px 0;
}

.re-hdr {
  display: grid;
  grid-template-columns: var(--re-cols, 1fr 1fr 86px);
  gap: 4px;
  align-items: center;
  padding: 2px 0;
  position: sticky;
  top: 0;
  background: var(--panel);
  color: var(--text-dim);
  font-size: 11px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 4px;
  margin-bottom: 4px;
}

.re-row input {
  width: 100%;
  background: var(--base);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 3px 6px;
  font: inherit;
}

.re-row input:focus { outline: 1px solid var(--accent); outline-offset: -2px; }

.re-act { display: flex; gap: 2px; justify-content: flex-end; }

.re-act button {
  width: 24px;
  padding: 2px 0;
  font: inherit;
  font-size: 11px;
  background: var(--btn);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}

.re-act button:hover { background: var(--btn-hover); border-color: var(--accent); }

.re-empty { padding: 18px 4px; color: var(--text-dim); }

.re-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

.re-foot button {
  padding: 3px 12px;
  font: inherit;
  background: var(--btn);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}

.re-foot button:hover { background: var(--btn-hover); border-color: var(--accent); }

.re-foot span { color: var(--text-dim); }

/* 위젯에 붙는 변수명 표시 */
.ffield {
  position: absolute;
  right: -1px;
  bottom: -1px;
  padding: 0 4px;
  background: var(--ok);
  color: #fff;
  font-size: 9px;
  line-height: 13px;
  z-index: 3;
  pointer-events: none;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── v31 : 서버에서 열기 목록 ─────────────────────────────── */
/* v18 : 열이 4칸(1fr 60px 130px 110px)으로 쟡혀 있었으나 머리글도 행도 칸이 3개라
   마지막 110px 가 빈 칸으로 남고 '상태'가 버튼에서 멀어졌다.
   또 버튼 칸 130px 가 버튼 3개를 못 담아 글자가 두 줄로 깨졌다(로/그, 재시/작).
   3칸으로 맞추고 버튼 칸은 내용만큼 차지하게 한다. */
.sv-hdr,
.sv-row {
  display: grid;
  /* max-content 는 그리드마다 따로 계산된다 — 머리글은 3번째 칸이 비어 0px 가 돼
     행과 열이 어긋나갔다. 고정폭으로 둘 다 같은 자리에 서게 한다. */
  /* v19 : 이름 | 포트 | 상태 | 작업 — 네 칸.
     포트와 상태를 나누었다. 예전엔 '상태' 칸에 포트만 뗴어 정작 잘 돌아가는지를 몰랐다. */
  grid-template-columns: minmax(0, 1fr) 104px 76px 232px;
  gap: 10px;
  align-items: center;
  padding: 5px 2px;
  border-bottom: 1px solid var(--line);
}

.sv-list { max-height: 46vh; overflow: auto; }

.sv-row:hover { background: var(--group); }

.sv-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sv-n,
.sv-p,
.sv-t { color: var(--text-dim); font-size: 11px; white-space: nowrap; }

/* v19 : 상태 글자는 색으로 구분하므로 흘림색을 덮어쓴다(인라인이 이긴다). */
.sv-t { font-weight: 600; }

/* v19 : 이름으로 찾기 줄 */
.sv-find { display: flex; align-items: center; gap: 8px; padding: 2px 2px 8px; }

.sv-find input {
  flex: 1;
  min-width: 0;
  padding: 4px 8px;
  font: inherit;
  border: 1px solid var(--line);
  background: var(--base);
  color: var(--text);
}

/* v19 : 삭제는 되돌릴 수 없는 동작이라 색으로 구분해 둔다. */
.sv-act button.sv-del { color: #c0392b; }

/* v20 : 머리글을 눌러 정렬한다. 누를 수 있다는 것을 커서·밑줄로 알린다. */
.sv-sort {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.sv-sort:hover { text-decoration: underline; }

.sv-sort.on { font-weight: 600; color: var(--text); }

/* v19 : 포트 입력칸은 포트 칸 안에 꿉 차게 한다. */
.svc-port {
  box-sizing: border-box;
  padding: 2px 6px;
  font: inherit;
  font-size: 11px;
  border: 1px solid var(--line);
  background: var(--base);
  color: var(--text);
}

.sv-act { display: flex; gap: 4px; justify-content: flex-end; white-space: nowrap; }

.sv-act button {
  padding: 2px 9px;
  font: inherit;
  font-size: 11px;
  white-space: nowrap;
  background: var(--btn);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}

.sv-act button:hover { background: var(--btn-hover); border-color: var(--accent); }
/* ══ v11 : 문서 흐름형 페이지 캔버스 ══════════════════════════
   자유좌표를 걷어낸 뒤의 캔버스다. 블록은 순서대로 쌓이고 폭은 부모가 정한다.
   여기 있는 규칙 중 '폭'을 정하는 것은 .page-frame 의 max-width 하나뿐이며,
   그 값조차 app.js 가 뷰포트에 따라 인라인으로 준다. */

/* 반응형의 근원. 블록 안의 clamp(.., ..cqw, ..) 가 이 컨테이너 폭을 본다.
   container-type 은 이 파일 전체에서 여기 한 곳뿐이다 — 두 곳에 두면
   에디터와 내보내기의 1cqw 기준이 갈라진다(페이지빌더에서 넘어온 결함). */
/* 폼 자신이 페이지다. 래퍼를 만들지 않으므로 상자가 하나도 늘지 않는다.
   container-type 이 반응형의 근원이며 이 파일에서 여기 한 곳뿐이다.
   폭은 제한하지 않는다 — 폼(창) 폭이 곧 페이지 폭이다.
   패딩·테두리를 지우는 이유: 그만큼 블록 폭이 내보낸 결과물과 어긋난다(요구 5). */
/* [추가] CSS 버전 표식. 값이 아니라 표식이다 — 배치는 전부 인라인이 책임진다.
   app.js 가 기동 시 이 값을 읽어 파일이 옛 버전이면 상태줄로 알린다. */
:root { --af-css-ver: 20; }

/* 폼이 창의 남는 높이를 채운다.
   .formwin.maxi .form { min-height: 100% } 은 부모(.fw-body) 높이가 flex 로
   정해질 때 퍼센트가 해석되지 않아 폼이 내용 높이로 쪼그라들었다.
   부모를 세로 flex 로 만들고 폼에 flex 를 주면 브라우저와 무관하게 찬다. */
.fw-body.pg {
  display: flex;
  flex-direction: column;
}

/* [삭제] padding / border / background-image  (v15 — PAGE.formStyle() 로 이동) */
.form.pg {
  container-type: inline-size;
  flex: 1 0 auto;
}

/* 흐름형 블록 — 테두리 없음. 표시는 outline 으로만(배치에 영향이 없다). */
.form.pg .fnode {
  border: 0;
  background: transparent;
}

.form.pg .fnode:hover { outline: 1px solid var(--accent); outline-offset: -1px; }

/* 컨테이너 안쪽도 같은 흐름형 */
.form.pg .fkids { display: flex; flex-direction: column; align-items: stretch; }

/* [삭제] .form.pg .fnode > .fkids / .fkids.empty  (v15 — PAGE.kidsStyle() 로 이동) */
/* [삭제] .form.pg .fnode.sel|.primary > .pgh::after  (v15 — nodeHTML 의 gripCss 로 이동) */

/* 아래 가장자리 높이 손잡이. 폭 손잡이는 없다 — 폭은 사용자가 정하는 값이 아니다. */
/* [삭제] .pgh / .pgh::after / .pgh:hover::after  (v15)
   손잡이 위치·크기·그립 모양은 nodeHTML 이 인라인으로 낸다.
   CSS 가 옛 버전이어도 손잡이가 보이고 잡혀야 하기 때문이다. */

/* 툴바 뷰포트 버튼 — 아이콘 스프라이트가 아니라 글자라 크기를 따로 준다. */
.icon.vp { font-size: 13px; line-height: 1; }
