/* stidio — 고객용 모바일 웹 스타일시트
 *
 * 브랜드 가이드(BI_가이드라인 초안)를 그대로 옮긴 것이 위쪽 토큰이고, 아래는 그 토큰만
 * 쓰는 화면 규칙입니다. 색을 바꿀 일이 생기면 :root 만 고치면 됩니다.
 *
 * 밝은 화면인 이유: 만드는 물건이 흰 종이에 인쇄되는 스티커입니다. 어두운 배경에서는
 * 용지가 실제보다 밝아 보여서, 폰에서 고른 색과 나온 결과가 다르게 느껴집니다.
 * 스테이지만 한 단계 어두운 베이지(--surface-2)로 두어 흰 용지의 가장자리가 보이게 합니다.
 *
 * 버티는 범위는 이전과 같습니다: 360px 안드로이드, 노치 아이폰, 가로로 눕힌 태블릿.
 * 고정 픽셀 레이아웃 없음, 네 변 모두 safe-area 반영, 터치 영역 48px.
 */

/* ------------------------------------------------------------------ 서체 */

/* 본문용 서브셋(KS X 1001, 267KB). 화면에 쓰는 글자는 이걸로 충분합니다. */
@font-face {
  font-family: 'Pretendard';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/Pretendard-Regular.subset.woff2') format('woff2');
}
@font-face {
  font-family: 'Pretendard';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/Pretendard-SemiBold.subset.woff2') format('woff2');
}

/* 손님이 캔버스에 직접 넣는 글자는 서브셋에 없는 글자가 나올 수 있어 전체 자족을 씁니다.
   글자 도구를 처음 쓸 때 editor.js 가 불러옵니다 - 첫 화면에서 765KB 를 받게 하지
   않으려는 것입니다. */
@font-face {
  font-family: 'Pretendard Full';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/Pretendard-Regular.woff2') format('woff2');
}

/* 로고와 영문 포인트. 원본 로고 파일을 받기 전까지 워드마크도 이 조합으로 씁니다. */
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/InstrumentSerif-Regular.woff2') format('woff2');
}

/* ------------------------------------------------------------------ 토큰 */

:root {
  /* Primary / Sub — 브랜드 가이드 값 그대로 */
  --bg: #F8F6F0;              /* Off-White */
  --ink: #222222;             /* Deep Charcoal */

  --surface: #FFFFFF;
  --surface-2: #EAE6DB;       /* 캔버스 뒤 바닥 */
  --surface-3: #E4E1D8;
  --line: #CECCC5;
  --line-strong: #B4B1A6;

  --ink-2: #4F4F4F;
  --muted: #84827E;
  --muted-2: #9E9B92;

  /* 포인트 — 빨강은 오류와 칼선, 파랑은 선택과 진행 */
  --accent: #536A9F;
  --accent-soft: #eceff6;
  --danger: #DB0025;
  --danger-soft: #FCE8EB;
  --cut: #DB0025;             /* 칼선 표시색 */

  /* 주문 상태 알약에만 씁니다 - 완료(초록)·기다림(노랑) */
  --ok: #1F7A4D;
  --ok-soft: #E3F2E9;
  --amber: #8F5B00;
  --amber-soft: #FBEFD6;

  --tap: 48px;                /* 손가락이 편한 최소 크기 */
  --r-card: 16px;
  --r-btn: 12px;
  --r-chip: 999px;

  --shadow-1: 0 1px 2px rgba(34,34,34,.06), 0 2px 8px rgba(34,34,34,.05);
  --shadow-2: 0 6px 24px rgba(34,34,34,.10);
  --shadow-up: 0 -6px 24px rgba(34,34,34,.08);

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  background: var(--bg); color: var(--ink);
  font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo',
               'Segoe UI', 'Malgun Gothic', sans-serif;
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  /* 오브젝트를 끄는 동안 iOS 의 고무줄 스크롤과 안드로이드의 당겨서 새로고침이
     계속 끼어들기 때문에 둘 다 끕니다. */
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}

body {
  display: flex; flex-direction: column;
  height: 100vh; height: 100dvh;
  padding: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
}

/* -------------------------------------------------------------- 상단 바 */

.bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; background: var(--bg);
  border-bottom: 1px solid var(--line); flex: 0 0 auto;
  min-height: 52px;
}
.bar .title { font-weight: 600; font-size: 17px; white-space: nowrap; letter-spacing: -0.02em; }
.bar .spacer { flex: 1 1 auto; }
.bar .sub { font-size: 12px; color: var(--muted); white-space: nowrap;
            overflow: hidden; text-overflow: ellipsis; }

/* 로고: 업체 BI 원본(STIDIO_BXBI 의 sticker lab by stidio, 2026-10-20 받음)을 그대로 씁니다. 글자는 윤곽선이라
   글꼴과 상관없이 같은 모양입니다. 크기는 높이로만 정합니다(가로는 비율대로 약 5.2배). */
.logo { display: inline-flex; align-items: center; flex: 0 0 auto; }
.logo img { display: block; height: 24px; width: auto; }
a.logo { color: inherit; text-decoration: none; }
/* 첫 화면으로 돌아가는 작은 단추. 머리줄 오른쪽 끝. */
.bar a.home { margin-left: 10px; padding: 6px 12px; border: 1px solid var(--line); border-radius: 10px;
              font-size: 13px; color: var(--ink-2); text-decoration: none; white-space: nowrap;
              background: var(--surface); }

/* ------------------------------------------------------------ 진행 표시 */

/* 지금 어디쯤인지. 손님이 끝이 어딘지 알고 따라오게 하는 유일한 장치라 항상 보입니다. */
.progress {
  display: flex; align-items: center; gap: 0;
  padding: 10px 16px 12px; background: var(--bg); flex: 0 0 auto;
}
.progress .st { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.progress .st .n {
  width: 22px; height: 22px; border-radius: 50%; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600;
  background: var(--surface-3); color: var(--muted);
}
.progress .st .t { font-size: 12px; color: var(--muted); white-space: nowrap; }
/* 좁은 화면에서는 지금 단계의 이름만 남깁니다. 다섯 개를 모두 적으면 줄이 화면을
   밀어내고, 그러면 페이지 전체가 옆으로 스크롤됩니다. */
@media (max-width: 460px) {
  .progress .st .t { display: none; }
  .progress .st.on .t { display: inline; }
  .progress .ln { margin: 0 6px; }
}
.progress .st.on .n { background: var(--ink); color: var(--bg); }
.progress .st.on .t { color: var(--ink); font-weight: 600; }
.progress .st.done .n { background: var(--accent); color: #fff; }
.progress .ln { flex: 1 1 auto; height: 1px; background: var(--line); margin: 0 8px; }

/* ---------------------------------------------------------------- 컨트롤 */

button, .btn {
  appearance: none; border: 1px solid var(--line); background: var(--surface);
  color: var(--ink); border-radius: var(--r-btn);
  min-height: var(--tap); padding: 10px 14px;
  font-size: 15px; font-family: inherit; font-weight: 500;
  cursor: pointer; display: inline-flex; align-items: center; gap: 8px;
  justify-content: center; touch-action: manipulation; user-select: none;
  transition: background .12s ease, border-color .12s ease, transform .06s ease;
}
/* 단추 글자는 줄바꿈하지 않습니다. '번호 바꾸 / 기'처럼 꺾인 단추는 깨진 것처럼 보입니다(2026-09-22).
   글자가 길면 단추를 넓히거나 글자를 줄입니다. 여러 줄 내용을 담는 카드형 단추는 제외합니다. */
button:not(.tile):not(.store-row):not(.check-preview) { white-space: nowrap; }
button:active { transform: scale(.985); background: var(--surface-3); }
button:disabled { opacity: .4; }

/* 한 화면의 주 버튼은 하나. 그 하나가 이것입니다. */
button.primary {
  background: var(--ink); border-color: var(--ink); color: var(--bg); font-weight: 600;
}
button.primary:active { background: #000; }
/* 예전 이름이 남아 있는 화면이 있어 같은 모양으로 둡니다. */
button.go { background: var(--ink); border-color: var(--ink); color: var(--bg); font-weight: 600; }
button.danger { background: var(--surface); border-color: var(--danger); color: var(--danger); }
button.small { min-height: 38px; padding: 7px 12px; font-size: 13px; border-radius: 10px; }
button.on { background: var(--ink); border-color: var(--ink); color: var(--bg); }
button.ghost { background: transparent; border-color: transparent; color: var(--ink-2); }

/* 16px 미만이면 iOS 사파리가 입력할 때 화면 전체를 확대해 버립니다. */
input, select, textarea {
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
  border-radius: var(--r-btn); padding: 12px 14px; font-size: 16px; font-family: inherit;
  width: 100%; min-height: var(--tap);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
input::placeholder { color: var(--muted-2); }
input[readonly] { background: var(--surface-2); color: var(--ink-2); }
/* 라디오·체크박스는 위의 입력칸 모양(폭 100%·최소 높이·안쪽 여백)을 받지 않습니다. 받으면 아이폰
   사파리에서 동그라미가 칸을 크게 차지하고 옆 글자가 한 글자씩 꺾입니다. */
input[type=radio], input[type=checkbox] {
  width: auto; min-height: 0; padding: 0; margin: 0; border-radius: 0; box-shadow: none; flex: 0 0 auto;
}

/* ---------------------------------------------------------------- 스테이지 */

.stage {
  flex: 1 1 auto; position: relative; overflow: hidden; min-height: 0;
  background: var(--surface-2); display: flex; align-items: center; justify-content: center;
}
#canvas { touch-action: none; box-shadow: var(--shadow-2); display: block; }

/* ---------------------------------------------------------------- 도구 줄 */

/* 꾸미기 화면 아래에 늘 붙어 있는 줄. 참고 서비스들이 모두 이렇게 하고, 처음 쓰는
   사람이 무엇을 할 수 있는지 찾아다니지 않아도 됩니다. */
.tools {
  flex: 0 0 auto; background: var(--bg); border-top: 1px solid var(--line);
  padding: 8px 12px calc(8px + var(--safe-b));
  display: flex; flex-direction: column; gap: 8px;
}
.panel { display: flex; flex-direction: column; gap: 8px; }
.panel.hidden { display: none; }

.row { display: flex; gap: 8px; }
.row > button { flex: 1 1 0; min-width: 0; font-size: 13px; padding: 8px 4px; }
.row > button .lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 아이콘 위, 이름 아래. 글자만 있는 버튼보다 훑어보기가 빠릅니다. */
.toolrow { display: flex; gap: 6px; }
.toolrow > button {
  flex: 1 1 0; min-width: 0; flex-direction: column; gap: 4px;
  background: transparent; border-color: transparent;
  min-height: 60px; padding: 6px 2px; font-size: 12px; color: var(--ink-2);
}
.toolrow > button .ico { font-size: 21px; line-height: 1; }
.toolrow > button:active { background: var(--surface-3); }
.toolrow > button.on { background: var(--surface); border-color: var(--line); color: var(--ink); }

.tabs { display: flex; gap: 6px; border-top: 1px solid var(--line); padding-top: 8px; }
.tabs > button {
  flex: 1 1 0; min-width: 0; font-size: 13px; padding: 8px 2px;
  background: transparent; border-color: transparent; color: var(--muted);
}
.tabs > button.on { background: var(--surface); border-color: var(--line);
                    color: var(--ink); font-weight: 600; }

/* 화면 맨 아래 고정. 어느 단계에서든 다음으로 가는 버튼은 여기 하나뿐입니다. */
.cta {
  flex: 0 0 auto; padding: 10px 16px calc(12px + var(--safe-b));
  background: var(--bg); border-top: 1px solid var(--line);
  display: flex; gap: 10px;
}
.cta > button { flex: 1 1 auto; min-height: 54px; font-size: 16px; }
.cta > button.back { flex: 0 0 auto; min-width: 56px; padding: 10px; }

input[type=checkbox].chk {
  width: 26px; height: 26px; min-height: 26px; flex: 0 0 auto; accent-color: var(--accent);
}
/* 고르는 단추(라디오). 두 칸이 폭을 똑같이 나누고 글자는 한 줄로 둡니다 - 좁은 폰에서
   '만 / 19세 이상'처럼 꺾여 두 줄이 되면 옆 단추와 높이가 달라지고 읽기도 어렵습니다. */
input[type=radio].chk {
  width: 22px; height: 22px; min-height: 22px; margin: 0; flex: 0 0 auto; accent-color: var(--accent);
}
.row > label.btn { flex: 1 1 0; min-width: 0; justify-content: flex-start; white-space: nowrap;
                   padding: 10px 12px; }

/* 확인 화면: 작게 둔 미리보기(누르면 크게), 사진 바로 밑의 알약 선택 두 줄. */
.check-preview { position: relative; width: 100%; display: flex; align-items: center; justify-content: center;
                 padding: 12px; flex: 0 0 auto; background: var(--surface-2); border-color: transparent;
                 border-radius: var(--r-card); }
.check-preview img { display: block; max-width: 100%; max-height: 40vh; width: auto; height: auto; }
.check-preview .zoom-hint { position: absolute; right: 10px; bottom: 10px; font-size: 12px; font-weight: 500;
                            padding: 4px 10px; border-radius: 999px; background: rgba(255,255,255,.94);
                            border: 1px solid var(--line); color: var(--ink-2); }
.opt-row { display: flex; align-items: center; gap: 10px; }
.opt-label { flex: 0 0 64px; font-size: 13px; font-weight: 600; color: var(--ink-2); }
.seg { flex: 1 1 auto; display: flex; border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
       background: var(--surface); }
.seg > button { flex: 1 1 0; min-width: 0; min-height: 42px; padding: 6px 4px; border: 0; border-radius: 0;
                font-size: 14px; background: transparent; white-space: nowrap; }
.seg > button + button { border-left: 1px solid var(--line); }
.seg > button.on { background: var(--ink); color: var(--bg); font-weight: 600; }
#zoomBody { touch-action: none; overflow: hidden; }
#zoomImg { max-width: 100%; max-height: 100%; user-select: none; -webkit-user-drag: none;
           transform-origin: center center; will-change: transform; }

/* 출력 매장 목록. 매장이 수십 곳이 되어도 한 줄씩 짧게 두고, 찾기 칸으로 거릅니다. */
.store-search { width: 100%; font-size: 16px; }
.store-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.store-row { width: 100%; justify-content: space-between; text-align: left; gap: 10px;
             padding: 10px 12px; min-height: 58px; }
.store-row .sr-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.store-row .sr-main b { font-size: 15px; font-weight: 600; }
.store-row .sr-sub { font-size: 12px; color: var(--muted); font-weight: 400;
                     white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.store-row .sr-tag { flex: 0 0 auto; font-size: 12px; font-weight: 500; padding: 3px 9px; border-radius: 999px;
                     background: var(--surface-2); color: var(--ink-2); white-space: nowrap; }
.store-row .sr-tag.ok { background: #EAF3EC; color: #2E6B3F; }
.store-row .sr-tag.qr { background: #EDF1F8; color: #2F3F63; }
.store-row.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.store-row.on:disabled { opacity: 1; }
.store-row:disabled:not(.on) { opacity: .55; }
.store-more { width: 100%; min-height: 44px; font-size: 13px; }
.store-head { margin-top: 10px; font-size: 12px; font-weight: 600; color: var(--muted); }
.store-more.ghost { background: transparent; border-color: transparent; color: var(--muted); }

/* 확대·축소는 캔버스 위에 떠 있습니다. 도구 줄에 두면 그만큼 작품이 작아집니다. */
.zoombar {
  position: absolute; top: 10px; right: 10px; z-index: 5;
  display: flex; align-items: center; gap: 4px;
  background: rgba(255,255,255,.92); border: 1px solid var(--line);
  border-radius: var(--r-btn); padding: 4px; box-shadow: var(--shadow-1);
}
/* 되돌리기는 왼쪽 위. 확대는 오른쪽 위. 손가락이 가는 자리가 서로 겹치지 않습니다. */
.zoombar.left { left: 10px; right: auto; }
.zoombar button { min-height: 38px; width: 38px; padding: 0; font-size: 17px;
                  border-radius: 9px; border-color: transparent; background: transparent; }
.zoombar span { font-size: 11px; color: var(--muted); min-width: 40px; text-align: center; }

.app { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }

/* 태블릿은 큰 폰으로 취급합니다. 같은 순서, 같은 쌓임, 가운데 정렬로 폭만 제한합니다. */
@media (min-width: 700px) {
  .bar, .tools, .pad, .cta, .progress {
    padding-left: max(20px, calc((100% - 760px) / 2));
    padding-right: max(20px, calc((100% - 760px) / 2));
  }
  button, .btn { min-height: 52px; font-size: 16px; }
  .bar .title { font-size: 19px; }
  .note, .card .meta span { font-size: 14px; }
  .mcard { max-width: 760px; margin: 0 auto; border-radius: var(--r-card) var(--r-card) 0 0; }
}

/* -------------------------------------------------------------- 속성 편집 */

/* 선택한 오브젝트 위에 뜨는 작은 바. 캔버스 위에 떠 있어 화면 높이를 가져가지 않습니다. */
.selbar {
  position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%);
  z-index: 6; display: none; align-items: center; gap: 6px;
  background: rgba(255,255,255,.95); border: 1px solid var(--line);
  border-radius: var(--r-btn); padding: 6px 8px; max-width: calc(100% - 20px);
  box-shadow: var(--shadow-1);
}
.selbar.show { display: flex; }
.selbar > span {
  font-size: 12px; color: var(--muted); padding: 0 4px; max-width: 30vw;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; min-width: 0;
}
/* 단추는 모두 같은 높이, 한 줄. 폭이 모자라면 줄어드는 것은 앞의 이름표이고 단추가 아닙니다 -
   예전에는 '✎ 바꾸기'가 두 줄로 꺾여 혼자 세로로 길어졌습니다. */
.selbar > button { flex: 0 0 auto; height: 40px; min-height: 40px; min-width: 40px;
                   padding: 0 12px; font-size: 13px; white-space: nowrap; }

/* 아래에서 올라오는 속성 시트. fixed 라서 캔버스 크기를 건드리지 않습니다 -
   예전처럼 오브젝트를 고를 때마다 페이지가 줄었다 늘었다 하지 않습니다. */
.modal { position: fixed; left: 0; right: 0; bottom: 0; z-index: 45; display: none; }
.modal.show { display: block; }

.mcard {
  background: var(--surface); border-top: 1px solid var(--line);
  border-radius: var(--r-card) var(--r-card) 0 0; box-shadow: var(--shadow-up);
  padding: 12px 14px calc(14px + var(--safe-b));
  display: flex; flex-direction: column; gap: 10px;
  max-height: 74vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.mhead { display: flex; align-items: center; gap: 8px; }
.mhead b { font-size: 15px; font-weight: 600; }
.mhead .spacer { flex: 1 1 auto; }
.mbody { display: flex; flex-direction: column; gap: 10px; }
.mfoot { display: flex; gap: 10px; }
.mfoot > button { flex: 1 1 0; }
.mfoot > button.danger { flex: 0 0 104px; }

.line { display: flex; align-items: center; gap: 10px; }
.line label { font-size: 12px; color: var(--muted); width: 56px; flex: 0 0 auto; }
.line input[type=text], .line input[type=number] { font-size: 16px; padding: 11px 13px; }
.line input[type=color] { padding: 2px; height: 46px; min-height: 46px; width: 56px; }

/* -------------------------------------------------------------- 전체 화면 */

.sheet {
  position: fixed; inset: 0; background: var(--bg);
  display: none; flex-direction: column; z-index: 50;
  padding: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
}
.sheet.show { display: flex; }
.sheet .head { flex: 0 0 auto; padding: 14px 16px; font-size: 14px; color: var(--ink-2); }
.sheet .head b { font-weight: 600; }
.sheet .body { flex: 1 1 auto; position: relative; overflow: hidden; min-height: 0;
  display: flex; align-items: center; justify-content: center; background: var(--surface-2); }
.sheet .foot { flex: 0 0 auto; padding: 12px 16px calc(12px + var(--safe-b));
               display: flex; gap: 10px; flex-wrap: wrap; border-top: 1px solid var(--line); }
.sheet .foot > button { flex: 1 1 120px; min-height: 52px; }
#lassoCanvas, #retouchCanvas { touch-action: none; display: block; }

/* 다듬기: 도구는 3칸 두 줄(가로 = 방식, 세로 = 넣기·빼기). 되돌리기·확대·칼선 보기는 그림 위에 띄웁니다. */
.toolrow.rt-tools { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
/* 고른 도구는 검게. 지금 그림을 만지면 무엇이 일어나는지 한눈에 보여야 합니다. */
.toolrow.rt-tools > button.on { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.rt-over { position: absolute; display: flex; gap: 6px; z-index: 2; }
.rt-tl { top: 10px; left: 10px; }
.rt-tr { top: 10px; right: 10px; }
.rt-bl { bottom: 10px; left: 10px; }
.rt-over button { min-height: 36px; padding: 6px 12px; font-size: 13px; border-radius: 999px;
                  background: rgba(255,255,255,.94); border: 1px solid var(--line); box-shadow: var(--shadow-1); }
.rt-over button:disabled { opacity: .4; }
.rt-over button.on { background: var(--ink); color: var(--bg); border-color: var(--ink); }

/* 붓 굵기 조절. 손가락으로 끌 수 있게 손잡이를 키웁니다. */
input[type=range] {
  -webkit-appearance: none; appearance: none; background: transparent;
  min-height: 44px; padding: 0; border: none;
}
input[type=range]::-webkit-slider-runnable-track {
  height: 6px; background: var(--surface-3); border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 28px; height: 28px; margin-top: -11px;
  border-radius: 50%; background: var(--ink); border: 3px solid var(--surface);
  box-shadow: var(--shadow-1);
}

/* 기다리는 동안 덮는 화면.
 *
 * 사진 업로드와 배경 제거는 손님이 시킨 일이 아니라 시스템이 시간을 쓰는 구간입니다.
 * 두 번째 줄에 초를 세는 이유가 그것입니다 - 도는 원만 있으면 5초와 50초가 똑같아
 * 보이고, 손님은 멈춘 줄 알고 다시 누르거나 폰을 내려놓습니다. */
.busy {
  position: fixed; inset: 0; z-index: 55; display: none;
  flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 24px; text-align: center;
  background: rgba(248, 246, 240, .95);
}
.busy.show { display: flex; }
.busy .msg { font-size: 18px; font-weight: 600; }
.busy .note { max-width: 32ch; white-space: pre-line; }

.spin {
  width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto;
  border: 3px solid var(--line); border-top-color: var(--ink);
  animation: spin 900ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ 목록 */

.pad { padding: 16px; display: flex; flex-direction: column; gap: 14px;
       overflow-y: auto; -webkit-overflow-scrolling: touch; flex: 1 1 auto; min-height: 0; }

.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: 14px; display: flex; gap: 14px; align-items: center; box-shadow: var(--shadow-1);
}
.card img { width: clamp(64px, 18vw, 92px); aspect-ratio: 3/4; object-fit: contain;
            background: #fff; border: 1px solid var(--line); border-radius: 8px; flex: 0 0 auto; }
.card .meta { flex: 1 1 auto; min-width: 0; }
.card .meta b { display: block; font-size: 15px; font-weight: 600; overflow: hidden;
                text-overflow: ellipsis; white-space: nowrap; }
.card .meta span { font-size: 12px; color: var(--muted); }
.card .acts { display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; }

/* 주문 상태 알약. 목록에서 한눈에 갈리게 색으로 나눕니다:
   할 일이 남음(진한 파랑, 출력 대기) · 진행(연한 파랑) · 완료(초록) · 기다림(노랑) · 문제(빨강) · 끝남(회색). */
.st { display: inline-flex; align-items: center; gap: 6px; padding: 3px 11px 3px 9px;
      border-radius: var(--r-chip); font-size: 13px; font-weight: 700; line-height: 1.5;
      white-space: nowrap; margin-bottom: 6px; }
.st::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.st.todo { background: var(--accent); color: #fff; }
.st.prog { background: var(--accent-soft); color: var(--accent); }
.st.ok   { background: var(--ok-soft); color: var(--ok); }
.st.wait { background: var(--amber-soft); color: var(--amber); }
.st.bad  { background: var(--danger-soft); color: var(--danger); }
.st.off  { background: var(--surface-3); color: var(--muted); }
.card .meta .hint { font-size: 13px; color: var(--ink-2); margin-top: 2px; }
.card.st-off img { opacity: .55; }
.card.st-todo { border-color: var(--accent); }
.card .acts > button { min-width: 80px; }
.cards { display: flex; flex-direction: column; gap: 12px; }

/* 화면 구역. 한 번에 하나만 보입니다(.hidden 으로 숨김). */
.screen { }

/* 템플릿·규격처럼 그림으로 고르는 것들 */
.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (min-width: 560px) { .grid { grid-template-columns: repeat(3, 1fr); } }
.tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: 10px; display: flex; flex-direction: column; gap: 8px; cursor: pointer;
  text-align: left; min-height: 0;
}
.tile img { width: 100%; aspect-ratio: 3/4; object-fit: contain; background: #fff;
            border-radius: 10px; border: 1px solid var(--line); }

/* 아직 그림이 없는 상품·템플릿 자리를 흰 종이 모양으로 보여 줍니다. 비율이 실제
   용지와 같아서 4×6 과 6×8 의 차이가 눈으로 바로 들어옵니다. */
/* 종이 비율 그대로(4×6 은 2:3, 6×8 은 3:4)인데 높이를 묶어 둡니다. 비율만 맞으면
   두 규격의 차이는 눈에 들어오고, 타일이 화면을 다 먹지는 않습니다. */
.tile .paper {
  height: 118px; aspect-ratio: 2/3; margin: 0 auto; background: #fff;
  border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-1);
}
.tile .paper.tall { aspect-ratio: 3/4; }

/* 2x6 은 프린터가 반으로 자르는 띠. 종이 비율(1:3)이 그대로 보여야 4x6 과 구별됩니다. */
.tile .paper.strip { aspect-ratio: 1/3; }
.tile { align-items: stretch; text-align: center; }
.tile b { font-size: 14px; font-weight: 600; }
.tile span { font-size: 12px; color: var(--muted); }
.tile.on { border-color: var(--ink); box-shadow: 0 0 0 2px var(--ink) inset; }

/* 가로로 미는 카테고리 줄 */
.chips { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px;
         scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chips > button {
  flex: 0 0 auto; border-radius: var(--r-chip); min-height: 40px; padding: 8px 16px;
  font-size: 14px; background: var(--surface);
}
.chips > button.on { background: var(--ink); border-color: var(--ink); color: var(--bg); }

/* 수량 조절 */
.stepper { display: flex; align-items: center; gap: 12px; }
.stepper > button { width: 48px; min-width: 48px; padding: 0; font-size: 20px; }
.stepper > b { font-size: 18px; font-weight: 600; min-width: 40px; text-align: center; }

.note { font-size: 13px; color: var(--muted); line-height: 1.6; }
.note b { color: var(--ink-2); font-weight: 600; }
.err { color: var(--danger); font-size: 13px; }
.ok { color: var(--accent); }
.price { font-size: 20px; font-weight: 600; }

/* 경고 한 줄. 칼선 검사 결과처럼 손님이 고칠 수 있는 것을 알려줄 때 씁니다. */
.warn {
  display: flex; gap: 10px; align-items: flex-start;
  background: #fdf2f4; border: 1px solid #f3c9d1; border-radius: var(--r-btn);
  padding: 12px 14px; font-size: 13px; color: #8d1226; line-height: 1.55;
}
.warn.info { background: var(--accent-soft); border-color: #c8d1e4; color: #2f3f63; }

.steps { display: flex; flex-direction: column; gap: 10px; }
.step {
  display: flex; align-items: center; gap: 12px; padding: 14px;
  border: 1px solid var(--line); border-radius: var(--r-btn); background: var(--surface);
  color: var(--muted); font-size: 14px;
}
.step .dot { width: 10px; height: 10px; border-radius: 50%;
             background: var(--line-strong); flex: 0 0 auto; }
.step.active { color: var(--ink); border-color: var(--ink); }
.step.active .dot { background: var(--ink); }
.step.done { color: var(--ink-2); }
.step.done .dot { background: var(--accent); }
.step.fail { color: var(--danger); border-color: var(--danger); }
.step.fail .dot { background: var(--danger); }

/* 화면 제목. 위아래 여백을 좁게 둡니다 - 폰 한 화면에 내용이 더 들어오는 편이 낫고, 제목이
   화면의 1/10 을 차지하면 정작 고를 것이 아래로 밀립니다(2026-09-22, 세로 영역 절반으로). */
.big { font-size: 22px; font-weight: 600; text-align: center; padding: 4px 8px; line-height: 1.3;
       letter-spacing: -0.02em; }
.serif { font-family: 'Instrument Serif', serif; font-weight: 400; }
.center { text-align: center; }
.hidden { display: none !important; }

/* PIN 처럼 멀리서도 읽어야 하는 숫자 */
.code { font-size: 40px; font-weight: 600; letter-spacing: .18em; text-align: center;
        padding: 8px 0; }

.toast {
  position: fixed; left: 50%; bottom: calc(104px + var(--safe-b));
  transform: translateX(-50%);
  background: var(--ink); color: var(--bg); border-radius: var(--r-btn);
  padding: 12px 18px; font-size: 14px; z-index: 60; max-width: 88vw; text-align: center;
  box-shadow: var(--shadow-2);
}
