/* ============================================================
   KWONMO — dotimg.css
   도트(page/dotimg) 전용. 수치·색은 val.css 토큰만 쓴다.
   한 화면 안에 다 들어간다(페이지가 스크롤되지 않는다) — 작업판이 늘 보여야 옵션을 돌리며 결과를 판정할 수 있다.
   넓은 화면(태블릿 이상): 위 단계 탭 · 가운데 원본|결과 나란히 · 아래 옵션 독(묶음별 칸).
   폰: 위 단계 탭 · 작업판(원본/결과 탭) 고정 높이 · 아래 시트(핵심 묶음만, 나머지는 '세부 설정').
   ============================================================ */

[data-layout="plain"] .stage.dot-app {
  max-width: none; height: calc(100dvh - var(--header-total)); padding: var(--sp-sm) var(--sp-md);
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: var(--sp-sm);
}
.dot-app [hidden] { display: none !important; }

.dot-btn {
  padding: .35rem var(--sp-md); border: var(--hairline) solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font: inherit; font-size: .85rem; cursor: pointer;
}
.dot-btn-main { border-color: var(--accent); color: var(--accent); font-weight: 700; }

/* ---------- 단계 탭 ---------- */
.dot-top { display: flex; align-items: center; gap: var(--sp-sm); }
.dot-steps { flex: 1; min-width: 0; display: flex; gap: var(--sp-md); }
/* 작업층(이미지 수정 · 이펙트 · 출력) 묶음 — 이름은 마크업의 data-grp 를 위에 작게 */
.dot-step-grp { display: flex; flex-wrap: wrap; gap: var(--sp-xs); }
.dot-step-grp::before { content: attr(data-grp); flex-basis: 100%; color: var(--text-dim); font-size: .7rem; line-height: 1.2; }
.dot-step {
  display: flex; align-items: baseline; gap: .35em; padding: .35rem var(--sp-md);
  border: var(--hairline) solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text-mid); font: inherit; font-size: .85rem; cursor: pointer;
}
.dot-step b { color: var(--text-dim); font-size: .75rem; }
.dot-step[aria-selected="true"] { border-color: var(--accent); color: var(--accent); font-weight: 700; }
.dot-step[aria-selected="true"] b { color: var(--accent); }

/* ---------- 작업판 ---------- */
.dot-views { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-sm); min-height: 0; }
.dot-vtabs { display: none; }
.dot-pane {
  position: relative; min-height: 0; display: grid; place-items: center; overflow: hidden;
  border: var(--hairline) solid var(--line); border-radius: var(--radius-md); background: var(--surface-2);
}
.dot-pane-nm {
  position: absolute; left: var(--sp-sm); top: var(--sp-sm); padding: 0 var(--sp-sm);
  border-radius: var(--radius-sm); background: var(--surface); color: var(--text-mid); font-size: .75rem;
}
.dot-empty { color: var(--text-dim); font-size: .85rem; text-align: center; padding: var(--sp-md); }

/* ---------- 옵션 독 ---------- */
.dot-dock { min-height: 0; max-height: 40dvh; overflow-y: auto; border: var(--hairline) solid var(--line); border-radius: var(--radius-md); background: var(--surface); }
.dot-panel { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.dot-grp { display: flex; flex-direction: column; gap: var(--sp-sm); padding: var(--sp-sm) var(--sp-md); border-right: var(--hairline) solid var(--line); }
.dot-grp:last-child { border-right: 0; }
.dot-grp-nm { color: var(--text-dim); font-family: var(--ed-label); font-size: .75rem; font-weight: 700; }
.dot-more { display: none; }

.dot-chips { display: flex; flex-wrap: wrap; gap: var(--sp-xs); }
.dot-chip {
  padding: .2rem .65rem; border: var(--hairline) solid var(--line); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--text-mid); font: inherit; font-size: .8rem; cursor: pointer;
}
.dot-chip[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); font-weight: 700; }

.dot-nums { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-xs) var(--sp-sm); font-size: .8rem; color: var(--text-mid); }
.dot-nums label { display: flex; align-items: center; gap: var(--sp-xs); white-space: nowrap; }
.dot-nums input { width: 100%; min-width: 0; font: inherit; }
.dot-range { display: grid; grid-template-columns: 6.5em minmax(0, 1fr) 2.5em; align-items: center; gap: var(--sp-sm); font-size: .8rem; color: var(--text-mid); }
.dot-range output { text-align: right; color: var(--text); font-variant-numeric: tabular-nums; }
.dot-line { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-sm); }
.dot-check { display: flex; align-items: center; gap: var(--sp-xs); font-size: .8rem; color: var(--text-mid); }
.dot-info { color: var(--text-mid); font-size: .8rem; font-variant-numeric: tabular-nums; }
.dot-none { padding: var(--sp-md); color: var(--text-dim); font-size: .85rem; }
.dot-status { padding: 0 var(--sp-md) var(--sp-sm); color: var(--text-mid); font-size: .8rem; }
.dot-status:empty { display: none; }
.dot-status.is-error { color: var(--danger); }

/* ---------- 작업 이미지 · 프레임 ---------- */
.dot-pane-src { touch-action: none; user-select: none; cursor: move; }
.dot-views.is-over .dot-pane-src { border-color: var(--accent); }
/* 틀이 캔버스 크기에 딱 붙어 프레임 좌표가 캔버스 좌표와 같아진다. 프레임 밖 어둠은 틀 밖으로 새지 않게 자른다 */
.dot-work { position: relative; overflow: hidden; }
.dot-work-canvas { display: block; width: 100%; height: 100%; }
/* 3~5단계는 도트 결과가 원본 — 작업 이미지는 가린다(투명 자리로 비쳐 보이지 않게) */
.dot-work-canvas.is-under { visibility: hidden; }
.dot-in-canvas { position: absolute; left: 0; top: 0; image-rendering: pixelated; pointer-events: none; }
/* 투명(알파 0) 자리가 보이게 바둑판 바탕 */
.dot-work-canvas, .dot-out-canvas, .dot-in-canvas {
  background: repeating-conic-gradient(var(--line) 0 25%, var(--surface) 0 50%) 0 0 / 1rem 1rem;
}
.dot-pane-src.is-lasso { cursor: crosshair; }
.dot-pane-src.is-still { cursor: default; }
.dot-mask-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.dot-lasso { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.dot-lasso-shade { fill: rgba(0, 0, 0, .45); fill-rule: evenodd; }
/* 선 굵기는 화면 기준 — viewBox 가 이미지 px 라 그대로 두면 배율에 따라 굵어지거나 사라진다 */
.dot-lasso-line { fill: none; stroke: #fff; stroke-width: var(--stroke-2); stroke-dasharray: 6 4; vector-effect: non-scaling-stroke; }
.dot-work-canvas.is-px, .dot-out-canvas { image-rendering: pixelated; }
.dot-box {
  position: absolute; box-sizing: border-box; pointer-events: none;
  outline: var(--hairline) solid #fff; box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .45);
}
.dot-box.is-over { outline: var(--stroke-2) solid var(--warn); }
.dot-box-nm {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%); padding: 0 var(--sp-xs);
  background: rgba(0, 0, 0, .6); color: #fff; font-size: .7rem; white-space: nowrap;
}
.dot-handle {
  display: none; position: absolute; width: 1rem; height: 1rem; box-sizing: border-box;
  border: var(--stroke-2) solid #fff; background: var(--accent); pointer-events: auto;
}
.dot-box.is-free .dot-handle { display: block; }
/* 손잡이는 상자 안쪽 모서리에 — 틀이 overflow 를 자르므로 바깥에 두면 이미지 가장자리에서 잘린다 */
.dot-handle[data-h="nw"] { left: 0; top: 0; cursor: nwse-resize; }
.dot-handle[data-h="ne"] { right: 0; top: 0; cursor: nesw-resize; }
.dot-handle[data-h="sw"] { left: 0; bottom: 0; cursor: nesw-resize; }
.dot-handle[data-h="se"] { right: 0; bottom: 0; cursor: nwse-resize; }
@media (pointer: coarse) {
  .dot-handle { width: 1.75rem; height: 1.75rem; }
}
.dot-out-canvas, .dot-anim-canvas { display: block; }
/* 워커가 도는 동안 — 지금 보이는 결과가 설정보다 한 박자 늦다는 표시 */
.dot-app.is-busy .dot-out-canvas, .dot-app.is-busy .dot-in-canvas, .dot-app.is-busy .dot-anim-canvas { opacity: .55; }
.dot-anim-canvas.is-px { image-rendering: pixelated; }
.dot-hex { width: 100%; box-sizing: border-box; font-family: "JetBrains Mono", monospace; font-size: .8rem; }
.dot-pal { display: flex; flex-wrap: wrap; gap: var(--hairline); }
.dot-sw { width: 1.1rem; height: 1.1rem; border: var(--hairline) solid var(--line); }

/* 햄버거(FAB)가 떠 있는 폭(~1280px) — 독 마지막 줄이 FAB 에 가리지 않게 그 높이만큼 비운다 */
@media (max-width: 80em) {
  .dot-dock { padding-bottom: calc(var(--fab-size) + var(--fab-gap) + var(--safe-b)); }
}

/* ---------- 폰 ---------- */
@media (max-width: 48em) {
  [data-layout="plain"] .stage.dot-app {
    padding: var(--sp-xs) 0 0; gap: 0;
    /* 작업판은 고정 높이 — 시트를 펴도 그림이 밀려나지 않는다 */
    grid-template-rows: auto 46dvh minmax(0, 1fr);
  }
  .dot-top { padding: 0 var(--sp-sm) var(--sp-xs); }
  /* 폰: 묶음 이름은 자리를 먹어 숨기고, 묶음 사이만 넓게 띄워 가른다 */
  .dot-steps { display: grid; grid-template-columns: 2fr 2fr 1fr; gap: var(--sp-sm); }
  .dot-step-grp { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--hairline); }
  .dot-step-grp::before { content: none; }
  .dot-step { flex-direction: column; align-items: center; gap: 0; padding: .2rem 0; font-size: .75rem; line-height: 1.3; }
  .dot-open { padding-inline: var(--sp-sm); font-size: .75rem; }

  .dot-views { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); gap: 0; }
  .dot-vtabs { display: flex; border-top: var(--hairline) solid var(--line); }
  .dot-vtab {
    flex: 1; padding: .3rem 0; border: 0; border-bottom: var(--stroke-2) solid transparent;
    background: none; color: var(--text-dim); font: inherit; font-size: .8rem; cursor: pointer;
  }
  .dot-vtab[aria-selected="true"] { border-bottom-color: var(--accent); color: var(--accent); font-weight: 700; }
  .dot-pane { border-radius: 0; border-inline: 0; }
  .dot-pane-nm { display: none; }
  .dot-views[data-view="src"] .dot-pane[data-pane="out"],
  .dot-views[data-view="out"] .dot-pane[data-pane="src"] { display: none; }

  .dot-dock { max-height: none; border-inline: 0; border-bottom: 0; border-radius: var(--radius-md) var(--radius-md) 0 0; }
  .dot-panel { grid-template-columns: minmax(0, 1fr); }
  .dot-grp { border-right: 0; border-bottom: var(--hairline) solid var(--line); }
  .dot-dock:not(.is-more) .dot-grp:not([data-core]) { display: none; }
  .dot-more {
    display: block; width: 100%; padding: var(--sp-sm) var(--sp-md); border: 0;
    background: none; color: var(--text-mid); font: inherit; font-size: .85rem; text-align: left; cursor: pointer;
  }
  .dot-more::after { content: " ▾"; }
  .dot-dock.is-more .dot-more::after { content: " ▴"; }
}
