/* static/workspace.css — 패널 배치의 **구조**. 웹과 로컬 앱이 같이 쓴다 (2026-09-22).
 *
 * 비유: 이 파일은 가구를 **어디에 어떻게 놓느냐**만 적는다(왼쪽/오른쪽/아래, 폭, 스크롤되는 칸과
 * 고정되는 칸). 벽지와 조명 — 색·글자 크기·간격·앱다운 테두리 — 는 각자의 CSS 가 맡는다:
 *   웹  = static/corrector.css
 *   로컬 = static/desktop/theme.css   (여기 있던 도킹 **구조** 규칙을 이 파일로 옮겨 왔다)
 *
 * ⛔여기에 색·폰트 크기·밀도 토큰을 쓰지 않는다. 그 순간 웹이 앱 모습이 되거나 그 반대가 된다.
 * ⛔DOM 을 옮기지 않는다 — `#main-area` 가 flex 행이라 `order` 와 `flex-direction` 만으로 된다.
 *   `#timeline-panel`·`#rhythm-warning-panel` 은 `#view-row` 안 = corrector.js 영토라 건드리지 않는다.
 *
 * 상한은 **변수로** 받는다(`--dock-max-w` / `--dock-max-h`). 값을 주지 않으면 상한이 없다(=100%).
 *   웹  : 값을 안 준다 → 지금까지처럼 폭 고정(겉모습 변화 0)
 *   로컬 : theme.css 가 40% / 50% 를 준다 — 작은 창에서 악보 칸이 0px 로 사라지던 실측 때문이다.
 */

/* 손잡이(.dock-resizer)가 absolute 로 놓일 기준. */
#main-area { position: relative; }

/* ── 폭·높이 — workspace.js 가 --dock-w / --dock-h 로 준다 ─────────────────────────────
   ⛔`.collapsed` 가 아닐 때만 쓴다. 패널에 인라인 width 를 주면 `#mode-panel.collapsed { width:48px }`
     가 져서(인라인 > 클래스) 접기가 깨진다. */
#main-area[data-dock="left"],
#main-area[data-dock="right"]  { --dock-w-eff: min(var(--dock-w, 248px), var(--dock-max-w, 100%)); }
#main-area[data-dock="bottom"] { --dock-h-eff: min(var(--dock-h, 160px), var(--dock-max-h, 100%)); }

#main-area[data-dock="left"]  > #mode-panel:not(.collapsed),
#main-area[data-dock="right"] > #mode-panel:not(.collapsed) { width: var(--dock-w-eff); }

/* 오른쪽: 순서만 뒤로. #center-col 이 order 0 이므로 1 이면 뒤다. */
#main-area[data-dock="right"] > #mode-panel { order: 1; }

/* 아래: 상자를 세로로 쌓고 패널을 뒤로. 폭은 전체, 높이는 변수.
   ⛔`body.mode-styler` 는 제외한다 — 그때 #main-area 의 자식은 #mode-panel 이 아니라
     #styler-panel + #styler-panel-resizer + #center-col 이고(corrector.html), 세로로 쌓으면
     가로로 나란해야 할 스타일러 패널이 통째로 무너진다(실측 300x1052). */
body:not(.mode-styler) #main-area[data-dock="bottom"] { flex-direction: column; }
#main-area[data-dock="bottom"] > #mode-panel {
  order: 1; width: auto; height: var(--dock-h-eff); flex-shrink: 0;
}
#main-area[data-dock="bottom"] > #center-col { min-height: 0; }

/* ── 패널 안 두 칸: 고정 chrome + 스크롤 내용 (workspace.js makeChrome) ────────────────
     .dock-chrome  고정 — 도킹 버튼들 + 접기 버튼. 패널이 어느 쪽에 붙어 있든 늘 같은 자리.
     .dock-scroll  스크롤 — 원래 있던 내용 그대로.
   전에는 버튼이 내용의 일부라 휠로 내리면 같이 밀려 사라졌다.
   ⛔`:has(> .dock-chrome)` 로 **chrome 을 만든 경우에만** 건다. chrome 을 안 만드는 화면(지금 웹)에서
     패널의 overflow 를 바꾸면 있던 스크롤이 사라진다. */
#mode-panel:has(> .dock-chrome) { overflow: hidden; }
#mode-panel > .dock-chrome {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: flex-end;
}
#mode-panel > .dock-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column;
}
.dock-btns { margin-left: auto; display: inline-flex; }
#mode-panel.collapsed .dock-btns { display: none; }

/* ── 크기 조절 손잡이 — #main-area 의 직계 자식 ────────────────────────────────────────
   ⛔패널 안에 두면 패널이 스크롤될 때 같이 밀려 올라간다(workspace.js 주석의 실측).
   위치는 패널과 **같은 변수**(--dock-w-eff/--dock-h-eff)로 맞춘다. 따로 계산하면 창이 작아져
   상한이 걸리는 순간 손잡이만 어긋나 보이지 않는 띠가 마우스를 가로챈다(실측 23px 어긋남). */
.dock-resizer { position: absolute; z-index: 5; background: transparent; }
#main-area[data-dock="left"]   > .dock-resizer { top: 0; bottom: 0; left:  calc(var(--dock-w-eff) - 3px); width: 6px; cursor: col-resize; }
#main-area[data-dock="right"]  > .dock-resizer { top: 0; bottom: 0; right: calc(var(--dock-w-eff) - 3px); width: 6px; cursor: col-resize; }
#main-area[data-dock="bottom"] > .dock-resizer { left: 0; right: 0; bottom: calc(var(--dock-h-eff) - 3px); height: 6px; cursor: row-resize; }
/* ⛔손잡이를 숨겨야 하는 경우가 둘이다. `.collapsed`(접힘)와, 스타일러 모드가 `#mode-panel` 을 통째로
   `display:none` 하는 경로(corrector.css) — 후자는 클래스가 안 붙어 `:has(.collapsed)` 로 안 잡힌다.
   패널 없이 손잡이만 남으면 보이지 않는 6px 띠가 악보 위에서 마우스를 가로챈다(실측). */
#main-area:has(> #mode-panel.collapsed) > .dock-resizer,
body.mode-styler #main-area > .dock-resizer { display: none; }

/* 끄는 동안에는 폭 전환을 끈다 — workspace.js 가 .dock-dragging 을 붙였다 뗀다.
   corrector.css 의 `transition: width .2s` 가 살아 있으면 패널이 커서보다 0.2초 늦게 따라온다. */
#main-area.dock-dragging > #mode-panel { transition: none; }

/* ══ MML 편집 패널의 도킹 (2026-09-22) ═══════════════════════════════════════════════
   상자가 `#center-col` 이다 — 모드 패널(`#main-area`)과 **다른 상자**라 방향이 서로를 밟지 않는다.
   모드 패널을 아래에 붙여 `#main-area` 가 세로로 쌓여도 그 안의 `#center-col` 은 제 방향을 갖는다.
   ⛔`:has(> #mml-preview:not(.hidden):not(.ws-detached))` 로 **패널이 떠 있을 때만** 건다. MML 모드가 아닐 때(스타일러
     모드 포함) 방향을 바꾸면 악보 칸이 통째로 흐트러진다 — 속성은 남아 있어도 배치는 원래대로여야 한다. */
#center-col { position: relative; }        /* MML 손잡이·안내가 놓일 기준 */

/* 상한 40% / 60% — 모드 패널과 달리 **웹에도 준다**. MML 패널은 전에 떠 있었으므로 "겉모습 변화 0" 이
   걸려 있지 않고, 상한이 없으면 최소 창에서 악보가 사라진다:
   2026-09-22 실측(900x650, 앱): 상한 55% → 악보 칸 150px. 40% → 200px. 1280 이상에서는 400px 가
   상한보다 작아 상한이 아예 안 걸린다(1280: 40%=425 > 400). 높이는 60% — MML 은 모드 패널의 한 줄 띠와
   달리 도구줄+코드 상자가 들어가 50% 면 코드 상자가 잘린다(900x650 에서 184px 필요). */
#center-col[data-mml-dock="left"],
#center-col[data-mml-dock="right"]  { --mml-w-eff: min(var(--mml-w, 400px), var(--mml-max-w, 40%)); }
#center-col[data-mml-dock="bottom"] { --mml-h-eff: min(var(--mml-h, 260px), var(--mml-max-h, 60%)); }

/* 좌/우 = 가로로 나란히. 아래 = 지금처럼 세로로(기본값이라 따로 쓰지 않는다). */
#center-col[data-mml-dock="left"]:has(> #mml-preview:not(.hidden):not(.ws-detached)),
#center-col[data-mml-dock="right"]:has(> #mml-preview:not(.hidden):not(.ws-detached)) { flex-direction: row; }

/* ⛔`flex-shrink: 0` 이 없으면 악보가 자리를 요구할 때 패널이 눌려 폭 지정이 무시된다. */
#center-col > #mml-preview { flex: 0 0 auto; }
#center-col[data-mml-dock="left"]  > #mml-preview { order: -1; }
#center-col[data-mml-dock="right"] > #mml-preview { order: 1; }
#center-col[data-mml-dock="bottom"] > #mml-preview { order: 1; width: auto; }

#center-col[data-mml-dock="left"]  > #mml-preview:not(.collapsed),
#center-col[data-mml-dock="right"] > #mml-preview:not(.collapsed) { width: var(--mml-w-eff); }
#center-col[data-mml-dock="bottom"] > #mml-preview:not(.collapsed) { height: var(--mml-h-eff); }
#center-col.dock-dragging > #mml-preview { transition: none; }

/* 손잡이 — 패널과 **같은 변수**로 자리를 잡는다(따로 계산하면 상한이 걸리는 순간 어긋난다). */
#center-col[data-mml-dock="left"]   > .dock-resizer { top: 0; bottom: 0; left:  calc(var(--mml-w-eff) - 3px); width: 6px; cursor: col-resize; }
#center-col[data-mml-dock="right"]  > .dock-resizer { top: 0; bottom: 0; right: calc(var(--mml-w-eff) - 3px); width: 6px; cursor: col-resize; }
#center-col[data-mml-dock="bottom"] > .dock-resizer { left: 0; right: 0; bottom: calc(var(--mml-h-eff) - 3px); height: 6px; cursor: row-resize; }
/* 패널이 없거나 접혀 있으면 손잡이도 없다 — 안 그러면 보이지 않는 6px 띠가 악보 위에서 마우스를 가로챈다. */
#center-col:has(> #mml-preview.hidden) > .dock-resizer,
#center-col:has(> #mml-preview.ws-detached) > .dock-resizer,
#center-col:has(> #mml-preview.collapsed) > .dock-resizer { display: none; }

/* 별도 창으로 떼어 놓은 동안 — 이 창에서는 자리를 차지하지 않는다(내용은 분리 창이 그린다).
   ⛔`.hidden`(= MML 모드를 나감)과 뜻이 다르다. 떼어 놓은 것은 **열려 있는** 상태다. */
#mml-preview.ws-detached { display: none; }

/* ── 끌어서 도킹: 안내(Guide)와 미리보기(Preview) ──────────────────────────────────────
   ⛔`pointer-events: none` 이 핵심이다. 안내가 마우스를 받으면 끌기 중 커서 아래 요소가 바뀌어
     pointer capture 가 없는 경로(분리 창에서 보내 오는 좌표)에서 자리 판정이 흔들린다.
   실제로 칠하는 색은 각자의 CSS — 여기서는 **어디에 얼마만큼**만 정한다. */
.dock-guide { position: absolute; inset: 0; z-index: 30; pointer-events: none; }
.dock-guide[hidden] { display: none; }
/* 띠는 **가장자리만** 차지한다 — 가운데는 비워 둬야 악보를 보면서 놓을 자리를 고를 수 있다
   (지시서 §19). 크기는 900x650 에서도 칩이 안 잘리는 값으로 실측해 정한다. */
.dock-zone { position: absolute; display: flex; align-items: center; justify-content: center; }
.dock-zone[data-side="left"]   { left: 0; top: 0; bottom: 0; width: 17%; max-width: 190px; min-width: 96px; }
.dock-zone[data-side="right"]  { right: 0; top: 0; bottom: 0; width: 17%; max-width: 190px; min-width: 96px; }
.dock-zone[data-side="bottom"] { left: 0; right: 0; bottom: 0; height: 19%; max-height: 170px; min-height: 72px; }
/* 좌/우 띠에서는 아래 띠와 겹치지 않게 자리를 비워 둔다 — 겹치면 모서리에서 칩 둘이 포개진다. */
.dock-guide:has(.dock-zone[data-side="bottom"]) .dock-zone[data-side="left"],
.dock-guide:has(.dock-zone[data-side="bottom"]) .dock-zone[data-side="right"] { bottom: 19%; }

/* 칩 = 아이콘 + 짧은 방향말. 띠 가운데에 놓인다(겨눌 필요 없는 표지). */
.dock-chip { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
.dock-zone[data-side="bottom"] .dock-chip { flex-direction: row; gap: 6px; }

.dock-preview { position: absolute; }
.dock-preview[hidden] { display: none; }
/* 끄는 동안에는 글자가 잡히지 않게 — 패널 제목을 끌 때 악보 위 글자가 파랗게 선택되던 것을 막는다. */
body.ws-dragging { user-select: none; }

/* ══ 접힌 패널 = 가장자리 탭 (2026-09-23) ═══════════════════════════════════════════
   비유: 서랍을 닫아 두면 **손잡이와 이름표**는 밖에 남는다. 접힌 패널도 그래야 한다 —
   자리만 48px 비워 두면 "뭐가 접혀 있다"가 아니라 "여기가 왜 비었지"로 읽힌다.
   ⛔패널마다 다른 접힘 표현을 만들지 않는다. 여기(구조)와 desktop/theme.css(색)가 한 벌이고,
     다른 것은 이름뿐이다(data-ws-label, 등록 값 label).
   여기는 **어디에 얼마만큼**만 정한다. 색은 각자의 CSS 가 한다. */
:root { --ws-tab: 48px; }                 /* 접힌 띠의 두께 — 좌/우는 폭, 아래는 높이 */

.ws-collapse-btn { display: flex; align-items: center; justify-content: center; gap: 3px; cursor: pointer; }
/* 접혔을 때: 단추가 띠 전체를 채우는 **탭**이 된다. 이름표는 CSS 가 붙인다
   (단추의 글자는 화살표·숫자가 쓰므로, 이름은 ::after 로 따로 둔다 — 서로 덮어쓰지 않는다). */
/* ⛔`height: auto` 면 글자 높이만 차지한다 — 아래에 접혔을 때 탭이 13px 로 눌렸다(2026-09-23 실측).
   접힌 패널은 탭 하나가 전부이므로 탭이 띠를 **꽉 채워야** 누를 곳이 넓고, 색도 띠 전체로 읽힌다. */
#mode-panel.collapsed > .ws-collapse-btn,
#mode-panel.collapsed > * > .ws-collapse-btn,
#mml-preview.collapsed > .ws-collapse-btn,
#mml-preview.collapsed > * > .ws-collapse-btn { width: 100%; height: 100%; }
/* 접힌 패널 안의 감싸개(헤더·chrome)도 높이를 넘겨줘야 탭이 실제로 채운다. */
#mml-preview.collapsed > #mml-preview-header { height: 100%; }
.collapsed > .ws-collapse-btn::after,
.collapsed > * > .ws-collapse-btn::after { content: attr(data-ws-label); }
/* 좌/우에 접히면 세로 탭 — 이름은 세로쓰기, 화살표는 그대로 선다. */
.collapsed[data-ws-side="left"] > .ws-collapse-btn,
.collapsed[data-ws-side="left"] > * > .ws-collapse-btn,
.collapsed[data-ws-side="right"] > .ws-collapse-btn,
.collapsed[data-ws-side="right"] > * > .ws-collapse-btn {
  flex-direction: column; padding: 6px 0;
}
.collapsed[data-ws-side="left"] > .ws-collapse-btn::after,
.collapsed[data-ws-side="left"] > * > .ws-collapse-btn::after,
.collapsed[data-ws-side="right"] > .ws-collapse-btn::after,
.collapsed[data-ws-side="right"] > * > .ws-collapse-btn::after {
  writing-mode: vertical-rl; letter-spacing: .08em;
}
/* 오른쪽에 접히면 화살표가 위 — `[ ◀ MML ]` 처럼 읽힌다. */
.collapsed[data-ws-side="right"] > .ws-collapse-btn,
.collapsed[data-ws-side="right"] > * > .ws-collapse-btn { flex-direction: column-reverse; }
/* 아래에 접히면 가로 탭 — `▲ MML`. */
.collapsed[data-ws-side="bottom"] > .ws-collapse-btn,
.collapsed[data-ws-side="bottom"] > * > .ws-collapse-btn { flex-direction: row-reverse; gap: 6px; }
#mml-preview.collapsed[data-ws-side="bottom"] > #mml-preview-header { height: var(--ws-tab); }
/* 숫자 칸은 있을 때만 자리를 먹는다(모드 패널의 "확인이 필요한 곳" 개수). */
.ws-count:empty { display: none; }

/* 접힌 두께 — 두 패널이 같은 값을 쓴다(전에는 모드 48px / MML 34px 로 따로였다). */
#main-area > #mode-panel.collapsed { width: var(--ws-tab); }
#center-col > #mml-preview.collapsed { width: var(--ws-tab); }
#center-col[data-mml-dock="bottom"] > #mml-preview.collapsed { width: auto; height: var(--ws-tab); }
