/* ============================================================
   Kafka Roki — Card News Maker · UI 스타일 v2
   규칙: 모든 UI 폰트 ≥ 22px (Kafka Roki UI 헌법)
   ============================================================ */
:root{
  --bg:#0a0a09; --panel:#121211; --panel2:#1a1a17; --line:rgba(242,239,230,.12);
  --ink:#f2efe6; --mut:#8a877d; --acc:#c8ff00; --acc2:#3a6bff; --warn:#ff5a4d;
  --ease:cubic-bezier(.22,1,.36,1);
  font-size:22px;
}
*{box-sizing:border-box;}
html,body{margin:0;height:100%;}
body{
  background:var(--bg); color:var(--ink); font-size:22px; line-height:1.45;
  font-family:"Pretendard",system-ui,-apple-system,"Apple SD Gothic Neo","Malgun Gothic",sans-serif;
  -webkit-font-smoothing:antialiased;
}
button,input,select,textarea{font-family:inherit;font-size:22px;color:inherit;}
.serif{font-family:"Fraunces","Playfair Display",Georgia,serif;}

/* ---- 레이아웃 ---- */
.app{display:grid;grid-template-columns:300px 1fr 380px;height:100vh;}
.col{height:100vh;overflow-y:auto;}
.rail{background:var(--panel);border-right:1px solid var(--line);padding:20px 16px;}
.stage{background:radial-gradient(120% 120% at 50% 0%,#16181d 0%,#0a0b0e 70%);
  position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px;padding:28px;}
/* 미리보기 위에서 글자 직접 편집(인플레이스) */
.inline-edit{position:absolute;z-index:25;margin:0;padding:0;border:0;outline:none;
  background:transparent;caret-color:var(--acc);resize:none;overflow:hidden;
  box-sizing:border-box;white-space:pre-wrap;word-break:break-word;}
.inline-edit::selection{background:rgba(200,255,0,.35);}
.inspector{background:var(--panel);border-left:1px solid var(--line);padding:22px 20px;}

/* ---- 헤더 ---- */
.brandbar{display:flex;flex-direction:column;align-items:flex-start;gap:9px;margin-bottom:20px;}
.brandbar .krlogo{display:flex;align-items:center;gap:10px;font-size:30px;font-weight:800;
  font-family:'Bricolage Grotesque','Pretendard',sans-serif;letter-spacing:-.05em;color:var(--ink);}
.brandbar .krlogo .dot{width:12px;height:12px;border-radius:50%;background:var(--acc);flex:none;
  animation:krpulse 2.4s ease-in-out infinite;}
@keyframes krpulse{0%,100%{transform:scale(1);opacity:1;}50%{transform:scale(.5);opacity:.5;}}
.brandbar b{font-size:24px;font-weight:800;margin-left:22px;}

.sechead{color:var(--mut);font-size:22px;font-weight:700;letter-spacing:.4px;
  text-transform:uppercase;margin:22px 4px 12px;}

/* ---- 사진 카운터 ---- */
.photometer{background:var(--panel2);border:1px solid var(--line);border-radius:12px;
  padding:12px 14px;margin-bottom:14px;font-size:22px;}
.photometer b{color:var(--acc);}
.photometer.warn{border-color:var(--warn);}
.photometer.warn b{color:var(--warn);}
.photometer small{display:block;color:var(--mut);font-size:22px;margin-top:4px;}

/* ---- 레일 도구 ---- */
.railtools{display:flex;gap:8px;margin-bottom:12px;}
.btn.sm{padding:10px 12px;font-size:22px;}
.railhint{color:var(--mut);font-size:22px;margin:0 4px 10px;}
/* 레일은 세로 플렉스 → 썸네일이 공간을 채우고 +슬라이드는 항상 맨 아래 */
.rail{display:flex;flex-direction:column;}
#thumbs{flex:1 1 auto;}
/* +슬라이드 추가 = 맨 하단 단독 배치(스크롤해도 바닥에 고정) */
.btn.addslide{position:sticky;bottom:0;margin-top:14px;flex:none;
  border:1.5px dashed rgba(200,255,0,.5);background:var(--panel);color:var(--acc);font-weight:700;
  box-shadow:0 -14px 18px -8px rgba(0,0,0,.55);}
.btn.addslide:hover{background:var(--panel2);border-color:var(--acc);}

/* ---- 슬라이드 썸네일 레일 ---- */
.thumb{position:relative;border:2px solid transparent;border-radius:14px;overflow:hidden;
  cursor:grab;background:var(--panel2);margin-bottom:10px;transition:border-color .2s var(--ease);}
.thumb:active{cursor:grabbing;}
.thumb.active{border-color:var(--acc);}
.thumb.dragging{opacity:.4;}
.thumb.dragover{border-color:var(--acc);border-style:dashed;}
.thumb-img{position:relative;line-height:0;}
.thumb-img canvas{display:block;width:100%;height:auto;}
.thumb .dot{position:absolute;bottom:8px;left:10px;width:14px;height:14px;border-radius:50%;
  background:#444;border:2px solid rgba(255,255,255,.4);pointer-events:none;}
.thumb .dot.hasphoto{background:var(--acc);}
/* 캡션 바 = 역할 라벨 + 호버 컨트롤(이미지 아래, 사진을 가리지 않음) */
.thumb .cap{position:relative;display:flex;align-items:center;min-height:46px;
  padding:7px 10px;background:var(--panel2);border-top:1px solid var(--line);overflow:hidden;}
.thumb .role{flex:1;min-width:0;font-size:22px;font-weight:600;line-height:1.2;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.thumb.active .role{color:var(--acc);}
/* 컨트롤(↑↓⧉✕) — 호버 시 캡션 우측에 정렬, 이미지와 안 겹침 */
.thumb .ctl{position:absolute;right:6px;top:50%;transform:translateY(-50%);display:flex;gap:4px;
  padding-left:12px;background:var(--panel2);opacity:0;pointer-events:none;transition:opacity .15s;}
.thumb .ctl::before{content:'';position:absolute;left:-22px;top:0;bottom:0;width:22px;
  background:linear-gradient(90deg,transparent,var(--panel2));}
.thumb:hover .ctl{opacity:1;pointer-events:auto;}
.thumb .ctl button{width:36px;height:36px;border:1px solid var(--line);border-radius:8px;cursor:pointer;
  background:var(--bg);color:var(--ink);font-size:22px;display:grid;place-items:center;line-height:1;
  transition:background .15s,color .15s,border-color .15s;}
.thumb .ctl button:hover{background:var(--acc);color:#0a0a09;border-color:var(--acc);}

/* ---- 버튼/필드 ---- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  border:1px solid var(--line);background:var(--panel2);color:var(--ink);
  border-radius:12px;padding:13px 16px;cursor:pointer;font-weight:600;
  transition:transform .12s var(--ease),background .2s,border-color .2s;width:100%;}
.btn:hover{background:#23262e;border-color:rgba(255,255,255,.2);}
.btn:active{transform:scale(.98);}
.btn.primary{background:linear-gradient(135deg,#c8ff00,#a6d400);border:none;color:#0a0a09;font-weight:800;}
.btn.accent{background:var(--acc);border:none;color:#0a0a09;font-weight:800;}
.btn.outline{background:transparent;border:1.5px solid var(--acc);color:var(--acc);font-weight:800;}
.btn.outline:hover{background:rgba(200,255,0,.10);border-color:var(--acc);}
.btn.deploy{background:linear-gradient(135deg,#3a6bff,#5b8cff);border:none;color:#fff;font-weight:800;}
.btn.deploy:hover{background:linear-gradient(135deg,#4f7dff,#6f9bff);border-color:transparent;}
.btn.ghost{background:transparent;}
.btn + .btn{margin-top:10px;}
.btnrow{display:flex;gap:10px;}
.btnrow .btn{margin-top:0;}
/* 값 안내 마퀴는 폰 폴백 화면(앱 셸이 안 뜬 화면)에서만 쓴다 — PC·앱 셸에선 값 알약이 그 일을 한다. */
.cn-paymarq{display:none;}
/* 도형 추가 3버튼(직사각형·정사각형·번호)은 좁은 인스펙터 칸에서도 절대 두 줄로 깨지지 않게 —
   한 줄 고정 + 칸을 고르게 나눠 갖고, 글꼴은 살짝 줄여 4글자가 여유 있게 든다(사장님 2026-07-19). */
.cm-addshapes{gap:8px;}
.cm-addshapes .btn{flex:1 1 0;min-width:0;white-space:nowrap;font-size:18px;padding:10px 8px;}

.savebar{background:var(--panel2);border:1px solid var(--line);border-radius:14px;padding:13px 13px 14px;margin-bottom:18px;}
.savebar-ttl{font-size:22px;font-weight:800;margin-bottom:10px;}
.savebar .btnrow .btn{margin-top:0;flex:1 1 0;min-width:0;white-space:nowrap;}
.savebar .btnrow .btn.accent{flex:1.2 1 0;}
/* 상단 저장바 — 슬림(주요 버튼만) */
.savebar-top{padding:11px 12px;margin-bottom:16px;}
/* 작업을 다 끝낸 맨 하단 저장바 (스크롤 끝에서 한 번 등장, 고정 아님) */
.savebar-bottom{margin-top:22px;margin-bottom:0;}

.field{margin-bottom:16px;}
.field label{display:block;color:var(--mut);font-size:22px;font-weight:600;margin-bottom:7px;}
.field .hint{color:var(--mut);font-size:22px;font-weight:400;opacity:.8;}
.field input,.field textarea,.field select{
  width:100%;background:var(--panel2);border:1px solid var(--line);border-radius:11px;
  padding:11px 13px;color:var(--ink);outline:none;transition:border-color .2s;}
.field textarea{min-height:92px;resize:vertical;line-height:1.5;}
.field input:focus,.field textarea:focus{border-color:var(--acc);}
.field.en input{font-family:"Fraunces",serif;font-style:italic;}
.field select{appearance:none;-webkit-appearance:none;cursor:pointer;font-weight:600;padding-right:40px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a877d' stroke-width='2.6' 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 13px center;}
.field select:hover{border-color:rgba(242,239,230,.28);}
.field select:focus{border-color:var(--acc);}
.field select option{background:var(--panel2);color:var(--ink);}

/* 악센트 직접 지정 도구 */
.accent-tool .acc-presets{display:flex;flex-wrap:wrap;gap:7px;margin:9px 0 11px;}
.accent-tool .acc-sw{width:30px;height:30px;border-radius:8px;cursor:pointer;border:2px solid transparent;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.16);transition:transform .12s var(--ease);}
.accent-tool .acc-sw:hover{transform:scale(1.14);}
.accent-tool .acc-sw.active{border-color:#fff;box-shadow:0 0 0 2px var(--acc),inset 0 0 0 1px rgba(0,0,0,.3);}
.accent-tool .acc-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.accent-tool .acc-color{width:48px;height:44px;min-width:48px;padding:3px;border:1px solid var(--line);
  border-radius:11px;background:var(--panel2);cursor:pointer;flex:none;}
.accent-tool .acc-hexwrap{display:flex;align-items:center;gap:3px;background:var(--panel2);
  border:1px solid var(--line);border-radius:11px;padding:0 11px;transition:border-color .2s;}
.accent-tool .acc-hexwrap:focus-within{border-color:var(--acc);}
.accent-tool .acc-h{color:var(--mut);font-size:22px;font-weight:700;}
.accent-tool .acc-hex{width:96px;background:none;border:none;color:var(--ink);font-size:22px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;padding:9px 0;border-radius:0;}
.accent-tool .acc-hex:focus{border-color:transparent;}
.accent-tool .acc-hex.bad{color:var(--warn);}
/* 하이라이트 박스 색: 2열 · 색·코드 한 줄 · 정사각형 꽉찬 컬러칩 */
#pillColorWrap{display:grid;grid-template-columns:1fr;gap:12px;}   /* 22px 색상칸이 잘리지 않도록 1열 */
#pillColorWrap .pcol label{display:block;font-size:22px;color:var(--mut);margin:0 0 5px;}
#pillColorWrap .acc-row{display:flex;align-items:center;gap:6px;flex-wrap:nowrap;}
#pillColorWrap .acc-color{width:36px;height:36px;min-width:36px;padding:0;border:1px solid var(--line);border-radius:8px;background:none;cursor:pointer;flex:none;}
#pillColorWrap .acc-color::-webkit-color-swatch-wrapper{padding:0;}
#pillColorWrap .acc-color::-webkit-color-swatch{border:none;border-radius:7px;}
#pillColorWrap .acc-hexwrap{display:flex;align-items:center;gap:2px;background:var(--panel2);border:1px solid var(--line);border-radius:8px;padding:6px 9px;flex:1;min-width:0;transition:border-color .2s;}
#pillColorWrap .acc-hexwrap:focus-within{border-color:var(--acc);}
#pillColorWrap .acc-h{color:var(--mut);font-size:22px;font-weight:700;}
#pillColorWrap .acc-hex{width:100%;background:none;border:none;color:var(--ink);font-size:22px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;min-width:0;padding:2px 0;}
.accent-tool .acc-eyedrop{flex:none;width:44px;height:44px;display:flex;align-items:center;justify-content:center;
  background:var(--panel2);border:1px solid var(--line);border-radius:11px;color:var(--ink);cursor:pointer;
  transition:border-color .18s,background .18s;}
.accent-tool .acc-eyedrop[hidden]{display:none;}   /* EyeDropper 미지원 브라우저: display:flex가 hidden을 덮지 않도록 */
.accent-tool .acc-eyedrop:hover{border-color:var(--acc);background:#21241b;}
.accent-tool .acc-eyedrop svg{width:18px;height:18px;}

.chips{display:flex;flex-wrap:wrap;gap:8px;}
.chip{border:1px solid var(--line);background:var(--panel2);border-radius:10px;
  padding:9px 13px;cursor:pointer;font-size:22px;transition:all .18s var(--ease);}
.chip:hover{border-color:var(--acc);background:#21241b;}
.chip.active{background:var(--acc);color:#14161a;border-color:var(--acc);font-weight:700;}
.chip.active:hover{background:var(--acc);}

/* ---- 팔레트 ---- */
.palbox{background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:14px;margin-bottom:14px;}
.palrow{display:flex;gap:8px;margin-bottom:10px;}
.palrow .sw{flex:1;height:42px;border-radius:9px;border:1px solid rgba(255,255,255,.15);}
.palbox .lbl{color:var(--mut);font-size:22px;}

.slider{width:100%;}
/* 두 칸 폼: 라벨 길이가 달라도 입력칸 바닥을 맞춘다(예: 스튜디오 ↔ VOL) */
.row2{display:flex;gap:14px;align-items:flex-end;}
.row2 .field{min-width:0;}
.row2 .field label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

/* 레이아웃(아키타입) 버튼 그리드 — 2열, 구분 없이 균일 버튼 */
#archChips{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
#archChips .chip{display:flex;align-items:center;justify-content:center;text-align:center;
  padding:13px 8px;font-weight:700;font-family:inherit;line-height:1.2;}
/* 미리보기 캔버스는 PC 에선 숨긴다 — PC 는 원래대로 글자 칩(사장님 : PC 3열 화면 불변) */
.chip-prev{display:none;}
/* 폰 앱(body.cnapp) 무드 단계 — 인스타 Edits 처럼 '지금 카드가 그 무드로 보이는' 미리보기 카드 그리드.
   활성은 라임 채움 대신 라임 테두리(속 그림자)로 — 그래야 미리보기가 안 가려진다. */
body.cnapp #archChips .chip{flex-direction:column;gap:8px;padding:8px;overflow:hidden;height:auto;}
body.cnapp #archChips .chip-prev{display:block;width:100%;height:auto;border-radius:8px;background:#000;
  box-shadow:0 2px 8px rgba(0,0,0,.4);}
body.cnapp #archChips .chip-lbl{font-size:20px;font-weight:700;line-height:1.15;}
body.cnapp #archChips .chip.active{background:var(--panel2);color:inherit;border-color:var(--acc);
  box-shadow:0 0 0 2px var(--acc) inset;}

/* ---- 서체 미리보기 카드 그리드 — PC 는 셀렉트 그대로, 폰 앱은 폰트를 '그 폰트로' 보여주는 카드 ---- */
.font-grid{display:none;}                                   /* PC: 숨김(셀렉트 유지) */
body.cnapp .fontrow{flex-direction:column;align-items:stretch;gap:18px;}   /* 폰: 두 섹션을 세로로 */
body.cnapp .fontrow > .field{flex:none;}
body.cnapp #fontDisp, body.cnapp #fontBody{display:none;}   /* 폰: 셀렉트 숨김 */
body.cnapp .font-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px;}
body.cnapp .font-card{flex-direction:column;gap:6px;padding:14px 8px;overflow:hidden;height:auto;}
body.cnapp .font-card .font-samp{font-size:34px;line-height:1.15;color:var(--ink);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:100%;}
body.cnapp .font-card .chip-lbl{font-size:15px;color:var(--mut);font-weight:600;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:100%;}
body.cnapp .font-card.active{background:var(--panel2);color:inherit;border-color:var(--acc);
  box-shadow:0 0 0 2px var(--acc) inset;}
body.cnapp .font-card.active .chip-lbl{color:var(--acc);}
/* ⛔ 마우스·트랙패드가 달린 PC(터치겸용·200% 확대 포함)에선 앱 모드라도 서체를 카드로 펼치지 않는다 —
   네이티브 셀렉트를 되살려 '펼침'을 없앤다(사장님 2026-07-21). any-pointer:fine = 정밀 포인터가 하나라도 있음.
   진짜 폰(정밀 포인터 없음)에선 이 규칙이 안 걸려 카드 그리드가 그대로 유지된다. */
@media (any-pointer:fine){
  body.cnapp .font-grid{display:none;}
  body.cnapp #fontDisp, body.cnapp #fontBody{display:block;}
}

/* ---- 템플릿: PC 는 '무드별 템플릿' 버튼+모달 그대로, 폰 앱은 단계 안에 인라인 그리드(모달·탭 하나 줄임) ---- */
#tplInline{display:none;}
body.cnapp #openTpl{display:none;}
body.cnapp #tplInline{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:0;margin-top:4px;
  /* ⚠ overflow:visible 필수. .tpl-grid 가 overflow-y:auto 인데, CSS 규칙상 overflow-x 도 자동으로
     auto 가 되어 그리드가 제 좌우 끝에서 잘린다 → 고른 카드의 라임 테두리(outline offset 2 + 굵기 2
     = 카드 밖 4px)가 좌·우만 깎여 깨져 보였다(사장님 2026-07-20). 폰에선 시트(.cm-sheet-bd)가
     이미 스크롤을 맡으니 이 그리드는 스크롤할 필요가 없다. */
  overflow:visible;}
/* 비율·마스트헤드·스와이프 버튼 — 2등분(가로 꽉 차게) */
#ratioChips,#circleFill,#circleColor{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
#ratioChips{grid-template-columns:repeat(3,1fr);}   /* 4:5 · 1:1 · 9:16 세 칸(사장님 2026-07-21) */
#ratioChips .chip,#circleFill .chip,#circleColor .chip{display:flex;align-items:center;justify-content:center;text-align:center;padding:13px 8px;}
/* 마스트헤드·스와이프 — 진짜 라디오 버튼 */
.radios{display:flex;gap:8px;}
.row2 .field .radio,.radio{flex:1;display:flex;align-items:center;justify-content:center;gap:7px;padding:13px 6px;font-size:22px;
  font-weight:600;cursor:pointer;border:1px solid var(--line);border-radius:12px;background:var(--panel2);color:var(--ink);
  user-select:none;white-space:nowrap;overflow:visible;text-overflow:clip;transition:border-color .15s,background .15s;}
.radio:hover{border-color:var(--acc);}
.radio input{appearance:none;-webkit-appearance:none;width:19px;height:19px;margin:0;border:2px solid var(--mut);border-radius:50%;
  position:relative;flex:0 0 auto;transition:border-color .15s;}
.radio input:checked{border-color:var(--acc);}
.radio input:checked::after{content:"";position:absolute;inset:3px;border-radius:50%;background:var(--acc);}
.radio:has(input:checked){border-color:var(--acc);background:rgba(200,255,0,.08);}
/* 현재 레이아웃이 안 쓰는 입력칸 흐리게 + 안내 */
.field.muted > label,.field.muted input,.field.muted textarea{opacity:.4;}
.muted-note{display:none;color:var(--acc2);font-size:22px;margin-top:6px;line-height:1.4;font-weight:600;}
.field.muted .muted-note{display:block;}
/* 정렬 버튼 — 3등분 */
#alignChips{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;}
#alignChips .chip{display:flex;align-items:center;justify-content:center;}
#logoPos .chip{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;line-height:1.15;}
.toggle{display:flex;align-items:center;gap:10px;cursor:pointer;font-size:22px;}
.toggle input{width:24px;height:24px;}

/* ---- 스테이지 ---- */
#preview{border-radius:14px;box-shadow:0 30px 80px rgba(0,0,0,.55);max-height:70vh;width:auto;}
.stagebar{display:flex;gap:12px;align-items:center;color:var(--mut);font-size:22px;}
.toast{position:fixed;left:50%;bottom:30px;transform:translateX(-50%) translateY(20px);
  background:#23262e;border:1px solid var(--line);border-radius:12px;padding:14px 22px;
  font-weight:600;opacity:0;pointer-events:none;transition:all .3s var(--ease);z-index:200;}
/* ⛔ 토스트(200)는 결제창(.modal 100)·확인창(#confirmModal 120)보다 위여야 한다 — 50 이던 시절엔
   결제창의 "연락처를 정확히 입력해 주세요"·"아래 동의에 체크해 주세요"가 모달 뒤에 깔려 안 보였고,
   고객은 버튼이 먹통이라고 느꼈다. (명함 빌더·오브에서 똑같이 겪고 고친 증상) */
.toast.show{opacity:1;transform:translateX(-50%) translateY(0);}

::-webkit-scrollbar{width:10px;height:10px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:#a6d400;border-radius:8px;}
::-webkit-scrollbar-thumb:hover{background:var(--acc);}
*{scrollbar-color:#a6d400 transparent;}

/* 라운드형 박스 토글(마스트헤드·스와이프) — 라디오/체크박스 대체 */
.rtoggle{display:flex;align-items:center;gap:11px;width:100%;box-sizing:border-box;cursor:pointer;
  font-size:22px;font-weight:600;padding:13px 16px;border:1px solid var(--line);border-radius:14px;
  background:var(--panel2);color:var(--ink);user-select:none;transition:border-color .15s,background .15s;}
.rtoggle:hover{border-color:var(--acc);}
.rtoggle input{appearance:none;-webkit-appearance:none;width:22px;height:22px;margin:0;flex:0 0 auto;
  border:2px solid var(--mut);border-radius:7px;position:relative;transition:border-color .15s,background .15s;}
.rtoggle input:checked{border-color:var(--acc);background:var(--acc);}
.rtoggle input:checked::after{content:"✓";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  color:#0a0a09;font-size:16px;font-weight:900;}
.rtoggle:has(input:checked){border-color:var(--acc);background:rgba(200,255,0,.10);}

/* ---- 템플릿 버튼(레일) ---- */
.btn.tpl{background:linear-gradient(135deg,rgba(200,255,0,.16),rgba(58,107,255,.16));
  border-color:rgba(200,255,0,.35);font-weight:700;margin-bottom:12px;}
.btn.tpl:hover{background:linear-gradient(135deg,rgba(200,255,0,.26),rgba(58,107,255,.26));}

/* ---- 템플릿 모달 ---- */
.modal{position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;
  background:rgba(6,7,9,.72);backdrop-filter:blur(6px);padding:30px;
  opacity:0;pointer-events:none;transition:opacity .22s var(--ease);}
.modal.show{opacity:1;pointer-events:auto;}
.modal-card{background:var(--panel);border:1px solid var(--line);border-radius:20px;
  width:min(1080px,96vw);max-height:88vh;display:flex;flex-direction:column;overflow:hidden;
  box-shadow:0 40px 120px rgba(0,0,0,.6);transform:translateY(14px) scale(.985);transition:transform .26s var(--ease);}
.modal.show .modal-card{transform:none;}
.modal-head{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:15px 26px;border-bottom:1px solid var(--line);}
.modal-head b{font-size:26px;font-weight:800;}
.modal-head small{display:block;color:var(--acc);font-size:22px;font-weight:700;margin-top:3px;}
.modal-x{width:46px;height:46px;border:1px solid var(--line);border-radius:12px;background:var(--panel2);
  color:var(--ink);cursor:pointer;font-size:24px;flex:none;}
.modal-x:hover{background:var(--warn);border-color:var(--warn);color:#fff;}
.tpl-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;
  padding:16px 26px 20px;overflow-y:auto;flex:1;min-height:0;align-items:start;}
.tpl-card{background:none;border:0;border-radius:12px;overflow:visible;cursor:pointer;display:block;
  outline:2px solid transparent;outline-offset:2px;transition:transform .14s var(--ease),outline-color .18s;}
.tpl-card:hover{transform:scale(1.03);outline-color:var(--acc);}
.tpl-card{position:relative;}   /* 스켈레톤 오버레이 기준 */
.tpl-card .prev{width:100%;display:block;background:#000;aspect-ratio:4/5;height:auto;border-radius:10px;}
/* 로딩 스켈레톤 — 사진까지 완성될 때까지 카드(미리보기 영역)를 회색 셰이머로 덮는다(사장님 2026-07-21). */
.tpl-skel{position:absolute;top:0;left:0;right:0;aspect-ratio:4/5;border-radius:10px;overflow:hidden;
  z-index:2;pointer-events:none;background:#1a1a17;transition:opacity .3s ease;}
.tpl-skel::after{content:"";position:absolute;inset:0;
  background:linear-gradient(100deg,transparent 18%,rgba(255,255,255,.06) 44%,rgba(255,255,255,.13) 50%,rgba(255,255,255,.06) 56%,transparent 82%);
  transform:translateX(-100%);animation:tplshim 1.3s ease-in-out infinite;}
.tpl-skel.gone{opacity:0;}
@keyframes tplshim{100%{transform:translateX(100%);}}
@media (prefers-reduced-motion:reduce){ .tpl-skel::after{animation:none;} }
.tpl-card .tpl-name{font-size:22px;color:var(--txt2,#c8c6bf);text-align:center;margin-top:8px;font-weight:600;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

/* ---- 보관함 ---- */
.lib-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:16px;
  padding:18px 26px 22px;overflow-y:auto;}
.lib-empty{grid-column:1/-1;text-align:center;color:var(--mut);font-size:22px;line-height:1.6;padding:48px 8px;}
.lib-card{background:var(--panel2);border:1px solid var(--line);border-radius:14px;overflow:hidden;
  display:flex;flex-direction:column;}
.lib-thumb{width:100%;height:auto;display:block;background:#000;cursor:pointer;
  transition:opacity .15s var(--ease);}
.lib-thumb:hover{opacity:.86;}
.lib-meta{padding:11px 12px 13px;display:flex;flex-direction:column;gap:8px;}
.lib-name{width:100%;background:var(--panel);border:1px solid var(--line);border-radius:9px;
  color:var(--ink);font-size:22px;font-weight:700;padding:8px 10px;}
.lib-name:focus{outline:none;border-color:var(--acc);}
.lib-date{color:var(--mut);font-size:22px;}
.lib-actions{display:flex;gap:8px;}
.lib-actions .btn{flex:1 1 0;min-width:0;text-align:center;padding:12px 10px;font-size:22px;
  border:1px solid transparent;box-sizing:border-box;}
.lib-actions .btn.ghost{border-color:var(--line);}

/* ============================================================
   모바일(≤767px) — 문서형 세로 레이아웃.
   ⚠ 지금은 "셸 이전 폴백"이다 : 폰에서는 아래 앱 셸(body.cnapp)이 항상
   켜져서 이 블록은 스크립트 실행 전 첫 페인트와, 스크립트가 죽었을 때만
   보인다. 여기 값을 바꿔도 화면 변화가 없으면 그래서다. PC(768px~) 무관.
   ============================================================ */
@media (max-width:767px){
  html,body{height:auto;}
  /* 하단 고정 저장바 ≈92px(마퀴 26 + 버튼 50 + 여백) — 여백이 그보다 얇으면 페이지 끝이 가려진다 */
  body{padding-bottom:calc(112px + env(safe-area-inset-bottom));}
  .app{display:flex;flex-direction:column;height:auto;}
  .col{height:auto;overflow:visible;}

  /* 레일 → 상단 헤더 + 가로 슬라이드 스트립 */
  .rail{border-right:0;border-bottom:1px solid var(--line);padding:14px 14px 12px;}
  .brandbar{flex-direction:row;align-items:center;flex-wrap:wrap;gap:8px 14px;margin-bottom:12px;}
  .brandbar .krlogo{font-size:24px;}
  .brandbar b{margin-left:0;font-size:22px;}
  #thumbs{display:flex;gap:10px;overflow-x:auto;padding-bottom:6px;flex:none;
    -webkit-overflow-scrolling:touch;scroll-snap-type:x proximity;}
  .thumb{flex:0 0 148px;margin-bottom:0;scroll-snap-align:start;}
  .thumb .cap{min-height:40px;padding:5px 8px;}
  /* 터치엔 호버가 없다 — 고른 장만 컨트롤 노출. 캡션을 가리지 않게 이미지 위 오버레이로 */
  .thumb.active .ctl{opacity:1;pointer-events:auto;}
  .thumb .cap{position:static;}   /* ctl 의 기준을 캡션이 아니라 썸네일로 — 이미지 위에 뜨게 */
  .thumb .ctl{top:6px;right:6px;bottom:auto;transform:none;padding-left:0;background:transparent;gap:5px;}
  .thumb .ctl::before{display:none;}
  .thumb .ctl button{width:32px;height:32px;background:rgba(10,10,9,.72);border-color:rgba(242,239,230,.35);}
  .btn.addslide{position:static;box-shadow:none;margin-top:10px;padding:11px 14px;}

  /* 스테이지 → 위에 붙어 따라오는 미리보기 */
  .stage{position:sticky;top:0;z-index:30;padding:12px 12px 10px;gap:8px;
    border-bottom:1px solid var(--line);box-shadow:0 18px 30px -18px rgba(0,0,0,.7);}
  #preview{max-height:42vh;max-width:100%;touch-action:none;}  /* touch-action 없으면 드래그가 스크롤로 먹힌다 */
  .stagebar{flex-wrap:wrap;justify-content:center;row-gap:2px;}
  #dragHint,.stagebar span:has(+ #dragHint){display:none;}     /* 폰에선 자리만 차지(앞 · 구분점도 함께) */

  /* ── 저장 버튼 2개 → 하단 고정 바 ──
     ⛔ 예전엔 버튼마다 「라벨 + 가격」 2줄이라 이 바가 150px 이었다 — 폰 화면의 5분의 1을 값 안내가
        먹고 있었다(사장님 지시 2026-08-27 「하단 버튼이 너무 크고 자리를 많이 차지한다」).
        → 버튼은 한 줄, 값·안내는 위의 마퀴 한 줄(26px)로 흐른다. 바 전체가 ≈92px 이 된다.
     ⚠ 높이를 다시 키우면 위의 body padding-bottom · 아래 .toast bottom 두 숫자도 같이 볼 것. */
  .stage .btnrow{position:fixed;left:0;right:0;bottom:0;z-index:40;max-width:none!important;
    flex-wrap:wrap;gap:8px;
    margin:0;padding:0 12px calc(8px + env(safe-area-inset-bottom));
    background:rgba(10,10,9,.93);backdrop-filter:blur(10px);border-top:1px solid var(--line);}
  /* 라벨은 한 줄 — 값은 위의 마퀴가 말한다(cnUpdateUI 가 폰에선 짧은 라벨을 넣는다). */
  .stage .btnrow .btn{flex:1 1 0;min-width:0;padding:13px 8px;font-size:22px;line-height:1.15;
    white-space:nowrap;overflow:hidden;}
  .toast{bottom:calc(105px + env(safe-area-inset-bottom));width:max-content;max-width:92vw;text-align:center;}

  /* 값 안내 마퀴 — 하단 바 맨 윗줄에 눕는다(버튼 두 개 위, 폭 전체).
     ⚠ 18px 은 사이트 22px 하한의 **마퀴 예외**다 — 흐르는 글은 크면 몇 낱말밖에 못 지나간다
       (slots-badge.js·project.html 의 다른 마퀴와 같은 규칙. 한 군데만 되돌리지 말 것). */
  body:not(.cnapp) .stage .btnrow .cn-paymarq{display:block;order:-1;flex:0 0 100%;
    height:26px;overflow:hidden;margin:0 -12px;padding:0;white-space:nowrap;
    border-bottom:1px solid rgba(242,239,230,.10);}
  .cn-paymarq-in{display:inline-block;padding-left:100%;line-height:26px;
    font-size:18px;font-weight:700;letter-spacing:-.01em;color:#c8ff00;
    animation:cnPayMarq 26s linear infinite;}
  @keyframes cnPayMarq{0%{transform:translateX(0)}100%{transform:translateX(-100%)}}
  @media (prefers-reduced-motion:reduce){ .cn-paymarq-in{animation:none;padding-left:12px;} }

  /* 인스펙터 → 본문 패널 */
  .inspector{border-left:0;padding:18px 14px 8px;}

  /* 모달 — 화면 꽉 차게 */
  .modal{padding:10px;}
  .modal-card{max-height:94vh;}
  .modal-head{padding:13px 16px;}
  .tpl-grid{grid-template-columns:1fr 1fr;gap:12px;padding:12px 14px 16px;}
  .lib-grid{grid-template-columns:1fr 1fr;gap:12px;padding:14px 14px 18px;}
}

/* ============================================================
   폰 앱 셸 — 캔버스가 주인, 만드는 순서가 엄지 밑에 (명함 빌더와 같은 구조)
   ------------------------------------------------------------
   2026-07-17 사장님 지시 : "디지털 명함하고 똑같은 구조여야 돼. 내가 많이 다듬어놨거든."
   → demos/card-maker.html 의 #cmApp(인스타그램 Edits 식)을 그대로 옮겼다. 클래스 이름까지
     같게 뒀다(.cw-top · .cm-stage · .cm-ctrl · .cm-sheet · .cm-rail · .cm-step) — 두 파일을
     나란히 놓고 맞춰 보라고. 명함 쪽을 고치면 여기도 같이 고칠 것.

     ① 캔버스(.cm-stage)가 화면의 주인 — 카드 미리보기가 남는 높이를 전부 가진다.
     ② 도구 줄(.cm-rail)이 화면 맨 아래 — 카드뉴스를 만드는 순서가 왼→오른쪽으로 늘어선다.
        줄 자체를 손가락으로 밀어 옮겨 다니고, 지금 단계는 늘 화면 가운데로 따라온다.
     ③ 시트(.cm-sheet)엔 **한 번에 한 가지만** 담는다 → 스크롤로 뒤질 것이 없다.
     ④ 시트를 옆으로 밀면 앞뒤 단계로 간다.

   ⛔ 명함과 다른 점은 딱 둘이다(카드뉴스의 본질이라 어쩔 수 없다) :
     · 미리보기가 DOM 이 아니라 <canvas id="preview"> 한 장이다 → 명함처럼 "지금 고치는 자리"에
       라임 테두리(.kr-focus)를 두를 수 없다. 축소도 CSS(max-width/height)가 맡는다 —
       명함의 fit() 처럼 배율을 손으로 잴 일이 없다.
     · 장이 여럿이다 → 컨트롤 줄에 장 번호(.cm-nums)가 붙고, 그림 썸네일·추가·삭제는 '장' 단계에 있다.
       (2026-07-17 : 캔버스 밑 썸네일 줄 89px 을 걷어냈다 — 그게 곧 카드 크기였다. 345×431 → 390×488)
   ⛔ 캔버스 위는 사진·글자·도형을 끄는 자리다 → 명함처럼 캔버스를 옆으로 밀어 단계를 넘기지
      않는다(끌기와 부딪힌다). 단계 넘기기는 시트에서만 받는다.

   ⚠ 일부러 @media 밖에 뒀다 — 가로로 돌려 767px 를 넘어도 앱 배치가 유지돼야 한다.
   스위치는 body.cnapp 클래스(폰 로드에서만 붙는다) → PC 는 아무 효과 없음.
   ============================================================ */
body.cnapp{overflow:hidden;height:100vh;height:100dvh;padding-bottom:0;}
body.cnapp .app{display:none;}                 /* 원래 3열 껍데기(내용물은 셸로 이사) */
body.cnapp .toast{bottom:calc(120px + env(safe-area-inset-bottom));z-index:10001;}   /* 도구 줄 위로 — 모달보다도 위(결제 안내가 뒤에 깔리면 안 된다) */
body.cnapp .toast{max-width:calc(100% - 28px);width:auto;}   /* 좁으면 다섯 줄로 부풀어 시트를 덮는다 */
/* 키보드가 올라오면 브라우저는 '보이는 영역'만 줄인다(visualViewport). 셸을 그 크기에 맞추면
   시트·도구 줄이 키보드 위로 올라오고, 카드는 남는 높이에서 계속 보인다 → 그 자리에서 입력한다. */
/* ⛔ touch-action:manipulation — 브라우저 기본 '두 번 톡 = 확대'를 끈다.
   빠뜨렸더니 카드나 버튼을 톡톡 치는 순간 화면이 통째로 확대돼 버렸다(사장님 지적 2026-07-17
   : "기능이 잘 안되고 화면이 확대되어버려"). 앱은 톡톡 치는 화면이라 그 기본 동작이 곧 고장이다.
   ⚠ manipulation 은 스크롤·핀치는 그대로 두고 '두 번 톡 확대'만 끈다 → 시트 스크롤은 살아 있다. */
#cnApp{position:fixed;left:0;right:0;top:var(--vtop,0px);height:var(--vh,100dvh);
  z-index:60;display:flex;flex-direction:column;background:var(--bg,#0a0a09);overflow:hidden;
  touch-action:manipulation;}

/* ── 상단바 (인스타 Edits 배치) ──
   ✕ 닫기 · 제목 ⌄(프로젝트 메뉴) · 값 · [다음 ›] 알약 버튼. (대행은 2026-08-27 제목 ⌄ 메뉴로 내렸다) */
.cw-top{flex:none;display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--bg,#0a0a09);}
.cw-back{flex:none;display:flex;align-items:center;justify-content:center;width:38px;height:38px;
  color:var(--ink);background:none;border:0;padding:0;cursor:pointer;}
.cw-back .kri{width:24px;height:24px;}
.cw-ttl{flex:1 1 auto;min-width:78px;display:flex;align-items:center;gap:5px;
  font-family:inherit;font-size:clamp(18px,4.8vw,23px);font-weight:800;letter-spacing:-.02em;color:var(--ink);
  background:none;border:0;padding:4px 0;cursor:pointer;white-space:nowrap;overflow:hidden;}
.cw-ttl .cw-ttl-t{overflow:hidden;text-overflow:ellipsis;}
.cw-ttl .kri{flex:none;width:18px;height:18px;color:var(--mut,#8a877d);transition:transform .2s var(--ease);}
body.cnapp.menu-open .cw-ttl .kri{transform:rotate(180deg);}
/* 값 알약 — 「저장 1,000 KRW」. 누르면 언제 돈이 나가는지 한 문장이 뜬다.
   ⚠ 라벨(저장)은 번역 대상, 숫자는 아니다(.cwp-amt 에 data-no-translate). */
.cw-price{flex:0 1 auto;min-width:0;overflow:hidden;display:inline-flex;align-items:baseline;gap:5px;
  font-family:inherit;font-size:clamp(13px,3.4vw,16px);font-weight:700;color:var(--mut,#8a877d);
  white-space:nowrap;background:none;border:0;padding:2px 0;cursor:pointer;}
.cw-price .cwp-cap{font-weight:700;font-size:.86em;color:#c8ff00;opacity:.9;}
.cw-price:active{opacity:.6;}
.cw-proxy{flex:none;background:none;border:0;padding:2px 3px;margin:0 2px;font-family:inherit;font-size:12px;
  font-weight:700;line-height:1;color:#c8ff00;cursor:pointer;text-decoration:underline;text-underline-offset:2px;opacity:.92;}
.cw-proxy:active{opacity:.55;}
.cw-go{flex:none;display:flex;align-items:center;gap:3px;
  font-family:inherit;font-size:clamp(17px,4.5vw,21px);font-weight:800;letter-spacing:-.02em;
  background:#c8ff00;color:#0a0a09;border:none;border-radius:999px;padding:10px 14px 10px 17px;cursor:pointer;}
.cw-go .kri{width:19px;height:19px;stroke-width:2.4;}
/* 5초 동안 아무것도 안 하시면 「다음」이 스스로 숨을 쉰다 — 다음에 누를 곳을 알려 주는 신호.
   (사장님 점검 24번). 손가락이 닿는 순간 멈춘다. */
.cw-go.nudge{animation:cwNudge 1.5s var(--ease,ease) infinite;}
@keyframes cwNudge{
  0%,100%{transform:scale(1);box-shadow:0 0 0 0 rgba(200,255,0,.55);}
  45%{transform:scale(1.06);box-shadow:0 0 0 11px rgba(200,255,0,0);}
}
@media (prefers-reduced-motion:reduce){.cw-go.nudge{animation:none;}}

/* 프로젝트 메뉴 (제목 ⌄) — 보관함·저장·새로 만들기·템플릿·파일을 여기 넣었다(윗줄이 붐비면 제목이 잘린다) */
.cm-menu{position:absolute;left:10px;top:calc(var(--vtop,0px) + 54px);z-index:40;min-width:230px;
  display:none;flex-direction:column;padding:6px;
  background:var(--panel);border:1px solid var(--line);border-radius:16px;
  box-shadow:0 24px 50px -18px rgba(0,0,0,.85);}
body.cnapp.menu-open .cm-menu{display:flex;}
.cm-menu button{display:flex;align-items:center;gap:11px;width:100%;
  font-family:inherit;font-size:clamp(17px,4.4vw,21px);font-weight:700;color:var(--body,#c2bdb0);text-align:left;
  background:none;border:0;border-radius:11px;padding:12px 12px;cursor:pointer;white-space:nowrap;}
.cm-menu button:hover{background:var(--panel2,#1a1a17);color:var(--ink);}
.cm-menu button .kri{flex:none;width:21px;height:21px;}
.cm-menu button .n{flex:1;}
.cm-menu button .c{font-size:clamp(14px,3.6vw,17px);color:var(--mut,#8a877d);font-weight:600;}
.cm-menu .sep{height:1px;background:var(--line);margin:5px 8px;}
.cm-scrim{position:fixed;inset:0;z-index:39;display:none;}
body.cnapp.menu-open .cm-scrim{display:block;}

/* ── ① 캔버스 : 남는 높이를 전부 가진다 ──
   ⛔ 명함처럼 배율을 손으로 재지 않는다 — 카드는 <canvas> 한 장이라 CSS 가 알아서 맞춘다.
     (명함은 412×786 폰 목업이 화면보다 커서 scale() 로 줄이고 훑어야 했다. 카드는 다 들어온다.) */
/* ⛔ touch-action:none — 캔버스는 사진·글자·로고를 손가락으로 끄는 자리다. 브라우저 기본 동작
   (두 번 톡 확대·끌어서 스크롤)에 뺏기면 끌기가 안 먹거나 화면이 확대된다(명함 셸도 같은 값). */
.cm-stage{position:relative;flex:1 1 auto;min-height:0;overflow:hidden;background:#07070a;
  display:flex;align-items:center;justify-content:center;touch-action:none;}
/* ⛔ 여백 0 — 카드를 화면 폭에 딱 붙인다(사장님 지시 2026-07-17). 카드는 세로가 아니라 **가로**에
   막혀 있어서(390 화면에 374 카드) 좌우 8px 이 곧 카드 크기다. 지우면 390px → 카드가 4% 커진다. */
/* ⛔ height:auto 에 **!important 가 반드시 필요하다**. 미리보기(main.stage)는 class="col stage" 인데,
     상단 마퀴(30px)를 피하려고 index.html <head> 가 `.col{height:calc(100vh - 30px)!important}` 를
     박아 놨다. 폰에서 그게 814px 로 그대로 따라와 미리보기 칸(119px)을 695px 뚫고 나갔고,
     카드는 화면 밖 216px 지점에 그려져 통째로 잘려 보이지 않았다("미리보기 창이 보여야 편집을 하지").
     !important 는 !important 로만 이긴다 — 인라인 style 로도 안 눌린다(실제로 확인).
   ⛔ absolute + inset:0 인 것도 이유가 있다. 그냥 height:100% 로 두면 순환 참조라 안 풀린다 :
     .cm-stage 높이는 flex 가 자식 크기로 정하는데, 그 자식이 다시 부모의 100% 를 달라고 한다.
     inset:0 은 부모 네모에서 높이를 직접 받으므로 순환이 끊기고, 자식(카드)의 100% 도 같이 풀린다. */
body.cnapp .cm-stage .stage{position:absolute;inset:0;top:0;z-index:auto;width:auto!important;height:auto!important;
  min-height:0;max-height:none!important;
  padding:0;gap:0;border-bottom:0;box-shadow:none;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;}
/* ⛔ 카드가 **잘리면 안 된다**(사장님 지시 : "미리보기 창이 보여야 편집을 하지").
   예전엔 flex 자식으로 두고 max-height:100% 를 걸었는데, 그 퍼센트가 안 풀려서 카드가 늘 468px 로
   그려졌다. 시트가 큰 단계(머리글·로고·색상)에선 캔버스 칸이 119px 까지 눌리는데도 카드는 468px
   이라 349px 이 overflow:hidden 에 통째로 잘려 나갔다 — 카드가 작아진 게 아니라 잘린 것이었다.
   → absolute + inset:0 + margin:auto 로 바꾼다. 담는 상자(.stage)가 크기가 확정된 채라
     max-width/max-height 의 100% 가 확실히 풀린다 → 남는 자리에 맞춰 저절로 줄어든다.
   ⚠ object-fit:contain 으로 늘리면 안 된다 — 요소 네모가 그림보다 커져서 캔버스 좌표가 어긋나고
     사진·글자·로고 드래그가 엉뚱한 데를 잡는다. 지금 방식은 요소 네모 = 그림이라 좌표가 그대로다. */
body.cnapp #preview{position:absolute;inset:0;margin:auto;
  max-width:100%;max-height:100%;width:auto;height:auto;touch-action:none;
  /* 카드가 검정이어도 배경(#07070a)에서 떠 보이게 — 하얀 하이라이트 링 + 부드러운 그림자.
     ⛔ border 가 아니라 box-shadow 로 — 요소 네모 크기가 안 변해 캔버스 좌표가 그대로다(드래그 어긋남 방지). */
  border-radius:10px;
  box-shadow:0 0 0 1px rgba(242,239,230,.22), 0 10px 34px rgba(0,0,0,.7);}
/* 1:1 은 가로, 4:5 는 세로가 화면에 꽉 차 위·아래(폰 브라우저 주소창까지 겹치면 더더욱)가 잘려 보인다
   → 둘 다 카드를 10% 줄여 여백을 준다(1:1 이 "딱 좋다"던 그 여백을 4:5 에도 동일 적용 · 사장님 2026-07-21). */
body.cnapp.cn-sq #preview{max-width:90%;max-height:90%;}
body.cnapp:not(.cn-sq):not(.pvbig) #preview{max-height:90%;}   /* 4:5(세로) : 높이만 90% → 위·아래 여백 */
/* 카드 미리보기가 위(마퀴)·아래(컨트롤 버튼 줄)에 딱 붙지 않게 여백을 준다.
   ⛔ .stage 는 .cm-stage 안에서 position:absolute; inset:0 이라 부모의 padding 으론 안 밀린다
      (absolute 는 padding edge 기준 → padding-top 이 자식을 못 내린다. 옛 padding-top:26px 은 무효였다).
      그래서 .stage 자체의 top/bottom 을 직접 준다(사장님 2026-07-19).
   · 아래 여백(bottom:10px) : 카드 밑변이 재생·되돌리기 버튼 줄에 붙는 걸 띄운다(마퀴 유무 무관).
   · 마퀴(라임 띠 #kr-slots)가 상단바 바로 아래에 떠 카드 윗부분을 덮으므로,
     마퀴가 켜지면 그 높이만큼 top 을 내려 카드가 마퀴 아래에서 시작하게 한다.
     ⛔ 홍보 띠는 글씨 22px(사장님 규칙)이라 높이가 40px 이다 — 옛 26px 값(top:28px)으로 두면
        카드 윗부분이 띠에 잘린다. 띠 높이를 바꾸면 이 값도 같이 바꿀 것(assets/slots-badge.js). */
body.cnapp .cm-stage .stage{bottom:10px;}
/* ⛔ 2026-08-17 부터 마퀴는 **화면 맨 위**에 눕고, 상단바가 그 높이만큼 스스로 내려간다
   (assets/slots-badge.js). 그래서 카드를 또 내릴 필요가 없다 — 예전 top:42px 를 그대로 두면
   상단바와 카드 사이에 42px 짜리 검은 띠가 생긴다(실제로 그랬다).
   ⚠ 마퀴를 다시 상단바 아래로 내리기로 하면 이 값도 같이 되살릴 것. */
body.cnapp.kr-marq-on .cm-stage .stage{top:0;}
/* 사진·도형의 좌우 버튼(서브레일)이 위 버튼(제거·업로드 / 추가)에 딱 붙지 않게 간격(사장님 2026-07-18) */
body.cnapp #photoDetail, body.cnapp #shapeCtl{margin-top:14px;}
body.cnapp .cm-addshapes{gap:6px;}
/* 도형 추가 3버튼 — 한 줄 유지(2행 금지), 글자 안 넘치게 작게(사장님 2026-07-18) */
body.cnapp .cm-addshapes .btn{flex:1;min-width:0;white-space:nowrap;padding:11px 4px;font-size:clamp(13px,3.6vw,16px);}
/* 카프카로키 로고 안내 — 한 줄 작게 */
body.cnapp #wmNoteStep{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

/* ── 장 썸네일 폰 오버레이(사장님 2026-07-18) — 번호 좌상 · 역할 라벨 하중앙 · ‹›좌우중앙 · ✕우상 · ⧉우하.
   PC 는 아래 기존 .cap(역할+호버 컨트롤) 그대로. 오버레이는 body.cnapp 에서만. ── */
.th-num,.th-role,.th-btn,.thumb-add{display:none;}
body.cnapp .thumb .cap{display:none;}
body.cnapp .thumb .dot{display:none;}
body.cnapp .thumb .th-num{display:block;position:absolute;top:5px;left:8px;z-index:2;pointer-events:none;
  font-size:19px;font-weight:800;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.9);line-height:1;}
body.cnapp .thumb.active .th-num{color:var(--acc);}
/* 장 썸네일 카드 안에 뜨던 역할 문구(도입·문제·핵심·실행·마무리)는 고객 눈에 군더더기 → 숨김.
   장 번호(th-num)는 남겨 순서만 보이게 한다(사장님 2026-07-21). */
body.cnapp .thumb .th-role{display:none;}
body.cnapp .thumb .th-btn{display:flex;align-items:center;justify-content:center;position:absolute;z-index:3;
  width:30px;height:30px;border:none;border-radius:50%;cursor:pointer;padding:0;line-height:1;font-size:17px;
  background:rgba(10,10,9,.72);color:#f2efe6;}
body.cnapp .thumb .th-btn:active{background:var(--acc);color:#0a0a09;}
body.cnapp .thumb .th-prev{left:3px;top:50%;transform:translateY(-50%);}
body.cnapp .thumb .th-next{right:3px;top:50%;transform:translateY(-50%);}
/* 좌우 넘김(‹ ›)은 덜 도드라지게 — 작고 옅게(사장님 2026-07-19). 삭제·복제(✕·⧉)는 그대로. */
body.cnapp .thumb .th-prev,body.cnapp .thumb .th-next{width:24px;height:24px;font-size:14px;
  background:rgba(10,10,9,.36);color:rgba(242,239,230,.7);}
body.cnapp .thumb .th-del{top:3px;right:3px;}
body.cnapp .thumb .th-dup{bottom:3px;right:3px;}
/* ＋ 추가 타일 — 마지막 장 오른쪽에 붙는다 */
body.cnapp .thumb-add{display:flex;align-items:center;justify-content:center;flex:0 0 58px;align-self:stretch;
  min-height:120px;border:2px dashed var(--line);border-radius:14px;background:var(--panel2);color:var(--mut);
  font-size:30px;cursor:pointer;}
body.cnapp .thumb-add:active{border-color:var(--acc);color:var(--acc);}
body.cnapp #addSlide{display:none;}
body.cnapp .cm-stage .stagebar,body.cnapp .cm-stage .btnrow,body.cnapp .cm-stage .wmnote{display:none;}
body.cnapp .cm-stage .modehint{display:none;}

/* ── 컨트롤 줄 (Edits 의 재생·타임코드·되돌리기 줄) ──
   미리보기 바로 밑. 가운데 = 지금 어디쯤인지, 오른쪽 = 크게보기·되돌리기·다시하기. */
.cm-ctrl{flex:none;display:flex;align-items:center;gap:6px;padding:5px 10px;background:var(--bg,#0a0a09);
  /* 입력 시작 시 이 줄을 접는데(아래 kr-typing), display:none 으로 툭 사라지면 화면 전체가 확 튄다 →
     max-height·투명도·패딩을 부드럽게 줄여 접는다(사장님 2026-07-21). */
  overflow:hidden;max-height:70px;transition:max-height .22s var(--ease),opacity .18s var(--ease),padding .22s var(--ease);}
.cm-ctrl .mid{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;
  font-size:clamp(13px,3.4vw,16px);font-weight:700;color:var(--mut,#8a877d);letter-spacing:.04em;white-space:nowrap;}
.cm-ctrl .mid .mt{white-space:nowrap;}
.cm-ctrl .mid .mbar{width:56px;height:5px;border-radius:999px;background:rgba(242,239,230,.16);overflow:hidden;flex:none;}
.cm-ctrl .mid .mbar>i{display:block;height:100%;width:6%;background:#c8ff00;border-radius:999px;transition:width .28s var(--ease);}
.cm-ctrl .und{flex:none;display:flex;align-items:center;justify-content:center;width:40px;height:40px;
  color:var(--body,#c2bdb0);background:none;border:0;padding:0;cursor:pointer;}
.cm-ctrl .und .kri{width:23px;height:23px;}
.cm-ctrl .und:disabled{opacity:.28;cursor:default;}
/* ── 안① : 장 번호 (사장님 결정 2026-07-17) ──
   그림 썸네일 줄(89px)을 걷어낸 자리를 대신한다. 이미 있는 컨트롤 줄 안이라 **높이 추가가 0** 이고,
   장 바꾸기는 그대로 한 번 탭이다. 그림·추가·삭제·순서는 도구 줄의 '장' 단계에 있다. */
.cm-nums{flex:none;display:flex;align-items:center;gap:4px;overflow-x:auto;scrollbar-width:none;max-width:58%;}
.cm-nums::-webkit-scrollbar{display:none;}
.cm-nums button{flex:0 0 auto;width:28px;height:28px;padding:0;border-radius:8px;
  border:1px solid var(--line);background:var(--panel2);color:var(--body,#c2bdb0);
  font-family:inherit;font-size:14px;font-weight:800;line-height:1;cursor:pointer;}
.cm-nums button.on{background:var(--acc);border-color:var(--acc);color:#0a0a09;}
.cm-nums button.add{color:var(--acc);background:none;border-style:dashed;border-color:rgba(200,255,0,.5);}

/* ── ⤢ 카드 크게 보기 : 미리보기 우측 여백의 대각선 확대 아이콘(사장님 2026-07-19).
   ⛔ 라운드 박스·블러 없음 — 아이콘만. 밝은 카드 위에서도 보이게 그림자만 얹는다. ── */
.cm-peek{position:absolute;right:8px;bottom:8px;z-index:8;
  width:40px;height:40px;display:flex;align-items:center;justify-content:center;
  background:none;border:0;color:var(--body,#c2bdb0);cursor:pointer;}
.cm-peek .kri{width:26px;height:26px;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6));}
.cm-peek:active{color:var(--acc);}
body.cnapp.kr-typing .cm-peek{display:none;}
/* 홈 화면 앱 영역 — '저장' 오른쪽 레일 아이콘(homeAppBtn)을 누르면 하단 시트 팝업으로 열린다(사장님 2026-07-22).
   왜(혜택 3줄) + 어떻게(버튼 한 번). 팝업 안에선 이중 테두리 없이 그대로 흐른다(.ha-pop 아래). */
.cm-homeapp{padding:2px 0 0;}
.kr-inst-box.ha-pop{padding-top:20px;}
.kr-inst-box.ha-pop .kr-inst-row{margin-top:14px;}
/* 홈앱 팝업의 '닫기' 는 보조 버튼 — 라임 '홈 화면에 추가'(주 버튼)가 도드라지게. */
.kr-inst-box.ha-pop .kr-inst-ok{background:none;color:var(--mut,#8a877d);border:1px solid var(--line,#2c2b26);font-weight:700;}
.cm-homeapp .ha-h{font-size:16px;font-weight:800;color:var(--ink,#f2efe6);margin-bottom:6px;}
.cm-homeapp .ha-why{font-size:13.5px;line-height:1.55;color:var(--body,#c2bdb0);margin:0 0 10px;}
.cm-homeapp .ha-why-list{margin:0 0 14px;padding-left:18px;font-size:13px;line-height:1.75;color:var(--mut,#8a877d);}
.cm-homeapp .ha-why-list li::marker{color:var(--acc,#c8ff00);}
.cm-homeapp .ha-btn{width:100%;background:var(--acc,#c8ff00);color:#0a0a09;border:0;border-radius:12px;
  padding:13px;font-weight:800;font-size:15px;cursor:pointer;}
.cm-homeapp .ha-btn:active{transform:scale(.98);}
.cm-homeapp .ha-how{font-size:12px;line-height:1.5;color:var(--mut,#8a877d);margin:9px 2px 0;text-align:center;}
.cm-homeapp .ha-ok{font-size:13.5px;line-height:1.55;color:var(--acc,#c8ff00);margin:0;}
/* 인앱(카톡·인스타)·아이폰·크롬용 설치 안내 — 하단 시트(타사 참고 2026-07-22). */
.kr-inst-pop{position:fixed;inset:0;z-index:10002;background:rgba(6,6,5,.66);
  display:flex;align-items:flex-end;justify-content:center;}
.kr-inst-box{background:var(--panel,#161512);color:var(--ink,#f2efe6);border:1px solid var(--line,#2c2b26);
  border-bottom:0;border-radius:22px 22px 0 0;max-width:520px;width:100%;padding:22px 20px calc(20px + env(safe-area-inset-bottom));
  box-shadow:0 -18px 50px rgba(0,0,0,.55);animation:krInstUp .22s cubic-bezier(.2,.7,.3,1);}
@keyframes krInstUp{from{transform:translateY(28px);opacity:.5;}to{transform:none;opacity:1;}}
.kr-inst-h{font-size:18px;font-weight:800;margin:0 0 6px;}
.kr-inst-sub{font-size:13.5px;line-height:1.55;color:var(--mut,#8a877d);margin:0 0 14px;}
.kr-inst-steps{margin:0;padding-left:20px;font-size:15px;line-height:1.6;}
.kr-inst-steps li{margin-bottom:10px;}
.kr-inst-steps li:last-child{margin-bottom:0;}
.kr-inst-steps b{color:var(--acc,#c8ff00);}
.kr-inst-steps .hint{display:block;color:var(--mut,#8a877d);font-size:12.5px;line-height:1.45;margin-top:2px;}
.kr-inst-row{display:flex;gap:10px;margin-top:20px;align-items:stretch;}
.kr-inst-globe{flex:none;display:inline-flex;align-items:center;gap:6px;background:none;color:var(--body,#c2bdb0);
  border:1px solid var(--line,#2c2b26);border-radius:999px;padding:11px 15px;font-family:inherit;font-weight:700;font-size:14px;cursor:pointer;}
.kr-inst-globe .kri{width:19px;height:19px;flex:none;}
.kr-inst-globe:active{border-color:var(--acc,#c8ff00);color:var(--acc,#c8ff00);}
.kr-inst-ok{flex:1;background:var(--acc,#c8ff00);color:#0a0a09;border:0;border-radius:999px;padding:12px;font-weight:800;font-size:15px;cursor:pointer;}
/* 카드만 보는 화면 : 시트·컨트롤·도구 줄을 접는다 */
body.cnapp.pvbig .cm-sheet,body.cnapp.pvbig .cm-ctrl,body.cnapp.pvbig .cm-railwrap{display:none;}
/* 확대 판 — 이때만 손가락을 받는다(캔버스의 사진·글자 드래그와 안 부딪히게) */
.cm-zoompad{position:absolute;inset:0;z-index:6;display:none;touch-action:none;}
body.cnapp.pvbig .cm-zoompad{display:block;}
body.cnapp.pvbig #preview{transform-origin:center center;}
.cm-zoomhint{position:absolute;right:10px;top:10px;z-index:8;display:none;
  background:rgba(10,10,9,.6);border:1px solid rgba(242,239,230,.2);border-radius:8px;
  padding:4px 8px;font-size:14px;font-weight:800;color:var(--acc);pointer-events:none;}
.cm-zoomhint.on{display:block;}
/* ⛔ 명함의 '크게 보기(.cm-zoom · body.pvbig)' 는 여기 없다 — 일부러 뺐다.
   명함은 미리보기가 412×786 폰 목업이라 화면보다 길어서 시트를 접어야 전체가 보였다.
   카드뉴스는 4:5·1:1 뿐이라 카드가 이미 폭에 꽉 차 있어(390px 폰에서 374px) 시트를 접어도
   1px 도 안 커진다 → 눌러도 아무 일이 없는 버튼이 된다. 세로로 긴 비율이 생기면 그때 가져올 것. */
body.cnapp.kr-typing .cm-ctrl{max-height:0;opacity:0;padding-top:0;padding-bottom:0;pointer-events:none;}   /* 컨트롤 줄을 부드럽게 접어 자리를 준다(툭 사라지지 않게) */

/* ── ③ 시트 : 안에는 **기능만** ──
   ⛔ 제목·진행표시·앞뒤 화살표·닫기·손잡이가 없다. 지금 무엇을 하는 중인지는 아래 도구 줄에서
     그 아이콘만 라임색으로 켜져 있는 것으로 안다(이름도 그 밑에 적혀 있다).
   ⚠ 내용 높이에 딱 맞고(빈 여백 0), 넘치면 56vh 에서 스크롤된다. */
.cm-sheet{flex:0 0 auto;max-height:56vh;position:relative;z-index:2;display:flex;flex-direction:column;
  background:var(--panel);border-top:1px solid var(--line);border-radius:20px 20px 0 0;
  box-shadow:0 -20px 44px -26px rgba(0,0,0,.9);
  transition:min-height .22s var(--ease);}   /* 입력 시작 시 시트 크기가 확 바뀌지 않게 부드럽게(사장님 2026-07-21) */
.cm-sheet-bd{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  padding:11px 13px 9px;}
body.cnapp.kr-typing .cm-sheet{min-height:120px!important;}
/* 단계를 넘길 때 내용이 옆에서 밀려 들어온다 */
@keyframes cnIn{from{opacity:0;transform:translateX(var(--from,18px));}to{opacity:1;transform:none;}}
body.cnapp .cm-sheet-bd.slide{animation:cnIn .22s var(--ease);}

/* ── 한 화면에 한 기능 ──
   ⛔ 폰에서는 폼을 스크롤로 뒤지게 하지 않는다. 지금 단계의 입력칸 하나만 꺼내 놓는다.
   ⚠ 표시(data-f)가 없는 것은 폰에서 안 보인다 — index.html 의 인스펙터 칸에 data-f 를 붙일 것.
     키 목록은 셸의 STEPS 와 1:1 이다. PC 는 이 속성을 그냥 무시한다. */
body.cnapp #cnForm [data-f]{display:none;}
body.cnapp #cnForm [data-f].on{display:block;}
body.cnapp #cnForm [data-f].on+[data-f].on{margin-top:12px;}   /* 한 단계에 칸이 여럿일 때 */
body.cnapp #cnForm .sechead{display:none;}      /* 제목은 도구 줄이 말해 준다 — 두 번 쓰지 않는다 */
body.cnapp #cnForm .field{margin:0;}
body.cnapp #cnForm .savebar{border:0;padding:0;margin:0;}
/* 사업자정보 고지 — 고정 화면이 body 를 덮어 푸터가 뒤에 깔린다 → 스크립트가 저장 단계로 옮긴다.
   ⛔ 전자상거래법 표시의무이자 PG 심사 요건(결제 화면 상시 노출)이다. 지우지 말 것. */
body.cnapp #cnForm #krBizFoot{margin-top:18px;padding:14px 0 0;}

/* 선착순 배지 — 폰 앱 셸에서만 쓴다. PC 는 원래대로 상단 .kr-marq 마퀴가 맡는다(둘 다 뜨면 중복). */
body:not(.cnapp) #kr-slots{display:none!important;}

/* ── 저장 모달 : 스텝바이스텝 (사장님 지시 2026-07-17) ──
   ① 무엇을 하시겠어요?(이미지=유료 / 보관=무료) → ② 고른 갈래의 버튼만.
   ⛔ 대행 신청과 사업자정보는 .cm-svfoot(늘 보이는 바닥)에 둔다 — 결제 화면 상시 노출은
      전자상거래법 표시의무이자 PG 심사 요건이다. 단계(.cm-sv) 안으로 옮기지 말 것. */
.cm-svcard{width:min(560px,94vw);}
.cm-svcard .modal-head{padding:13px 16px;gap:10px;}
.cm-svcard .modal-head b{flex:1;min-width:0;font-size:clamp(19px,5vw,24px);}
.cm-svback{flex:none;width:42px;height:42px;display:flex;align-items:center;justify-content:center;
  background:var(--panel2);border:1px solid var(--line);border-radius:12px;color:var(--ink);cursor:pointer;}
.cm-svback .kri{width:22px;height:22px;transform:rotate(180deg);}   /* › 아이콘을 돌려 ‹ 로 쓴다 */
.cm-svbd{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:14px 16px;}
.cm-sv{display:none;}
.cm-sv.on{display:block;}
/* 1단계 큰 선택 버튼 */
.cm-svbig{display:flex;align-items:center;gap:13px;width:100%;text-align:left;
  background:var(--panel2);border:1px solid var(--line);border-radius:16px;padding:16px 15px;
  color:var(--ink);font-family:inherit;cursor:pointer;transition:.16s var(--ease);}
.cm-svbig + .cm-svbig{margin-top:10px;}
.cm-svbig:active{transform:scale(.99);}
.cm-svbig .kri{flex:none;width:26px;height:26px;color:var(--acc);}
.cm-svbig .kri:last-child{width:20px;height:20px;color:var(--mut);margin-left:auto;}
.cm-svbig .t{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.cm-svbig .t b{font-size:clamp(19px,5vw,23px);font-weight:800;letter-spacing:-.02em;}
.cm-svbig .t i{font-style:normal;font-size:clamp(15px,3.9vw,18px);font-weight:600;color:var(--mut);line-height:1.35;}
/* 2단계 — 미니 썸네일 골라서 저장 (사장님 지시 2026-07-17) */
.cm-svgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(78px,1fr));gap:9px;}
.cm-svth{position:relative;padding:0;border:2px solid var(--line);border-radius:11px;overflow:hidden;
  background:var(--panel2);cursor:pointer;line-height:0;transition:.14s var(--ease);}
.cm-svth img{display:block;width:100%;height:auto;opacity:.42;transition:opacity .14s;}
.cm-svth .n{position:absolute;left:4px;top:4px;min-width:19px;height:19px;border-radius:999px;
  background:rgba(10,10,9,.8);color:var(--mut);font-size:12px;font-weight:800;line-height:19px;text-align:center;}
.cm-svth.on{border-color:var(--acc);}
.cm-svth.on img{opacity:1;}
.cm-svth.on .n{background:var(--acc);color:#0a0a09;}
/* 고른 장에 체크 표시 — 색만으론 못 알아본다 */
.cm-svth.on::after{content:'✓';position:absolute;right:4px;top:3px;font-size:13px;font-weight:900;color:var(--acc);
  text-shadow:0 0 3px rgba(10,10,9,.9);line-height:1;}
.cm-svbar{display:flex;align-items:center;gap:9px;margin-top:12px;}
.cm-svall{flex:none;font-family:inherit;font-size:clamp(15px,3.9vw,17px);font-weight:700;white-space:nowrap;
  background:var(--panel2);border:1px solid var(--line);color:var(--body,#c2bdb0);border-radius:999px;padding:10px 13px;cursor:pointer;}
.cm-svcta{flex:1;min-width:0;font-size:clamp(17px,4.4vw,20px);font-weight:800;padding:14px 10px;white-space:nowrap;}
.cm-svcta:disabled{opacity:.4;cursor:default;}

/* 늘 보이는 바닥 : 대행 신청 + 사업자정보 */
.cm-svfoot{flex:none;border-top:1px solid var(--line);padding:10px 16px calc(10px + env(safe-area-inset-bottom));
  max-height:34vh;overflow-y:auto;}
.cm-svfoot #krBizFoot{margin-top:8px;padding:8px 0 0;}
/* 저장 단계 시트의 큰 버튼 */
.cm-savebig{width:100%;font-size:clamp(19px,5vw,23px);font-weight:800;padding:16px;}

/* ── ② 도구 줄 : 화면 맨 아래, 엄지가 닿는 곳 ──
   카드뉴스를 만드는 순서를 왼쪽에서 오른쪽으로 아이콘으로 늘어놓는다.
   ⚠ 이 줄은 '일부러' 가로로 흐른다 → 지금 단계는 centerRail() 이 화면 가운데로 데려온다. */
/* gap 0 → 12px : 단계 사이에 화살표(›)가 설 자리를 낸다 (사장님 지시 2026-08-17,
   명함 빌더와 같은 모양으로 — 「셀프제작 기능은 모두 이걸 반영한다」) */
.cm-rail{flex:none;position:relative;z-index:3;display:flex;gap:12px;
  overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;touch-action:pan-x;cursor:grab;
  padding:4px 6px calc(4px + env(safe-area-inset-bottom));
  background:var(--panel);border-top:1px solid var(--line);}
.cm-rail::-webkit-scrollbar{display:none;}
body.cnapp.rail-drag .cm-rail{cursor:grabbing;}
body.cnapp.rail-drag .cm-step{pointer-events:none;}   /* 끄는 도중엔 아이콘이 눌리지 않게 */
/* 단색 선 아이콘. 두께·글씨 크기는 명함 빌더와 같은 값이다(인스타 Edits 를 잰 값) :
   아이콘 25px · 라벨 13~15px · 칸 68px · 줄 높이 58px 안팎. */
.cm-step{flex:0 0 auto;position:relative;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  width:68px;min-height:52px;font-family:inherit;background:none;border:0;padding:2px;
  color:var(--mut,#8a877d);transition:color .16s var(--ease);}
.cm-step .kri{width:25px;height:25px;transition:transform .16s var(--ease);}
.cm-step .l{font-size:clamp(12px,3.3vw,15px);font-weight:600;line-height:1.1;letter-spacing:-.03em;
  text-align:center;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* ── 어디까지 왔는지 (사장님 지시 2026-08-17 · 명함 빌더와 같은 모양) ──
   ① 끝낸 단계는 **글씨가 라임**이다. ⛔ 테두리·동그라미를 두르지 말 것.
   ② 단계 사이에 화살표(›). 지나온 구간은 라임, 아직 안 온 구간은 흐린 회색.
   ⛔ 옛 ✓ 배지는 뺐다 — 라임 글씨가 이미 「끝났다」를 말하는데 배지까지 있으면 줄이 시끄럽다.
   ⚠ ::after 는 「지금 단계」 밑줄이 쓰고, ::before 는 화살표가 쓴다. 맨 끝 홈앱 아이콘
     (.cm-step-extra)은 단계가 아니므로 화살표에서 뺀다(제 ::before 로 구분선을 그린다). */
.cm-step.done{color:#c8ff00;}                                 /* 이미 채운 단계 */
.cm-step + .cm-step:not(.cm-step-extra)::before{content:'';position:absolute;left:-11px;top:50%;margin-top:-9px;
  width:6px;height:6px;border-right:1.6px solid rgba(242,239,230,.26);border-top:1.6px solid rgba(242,239,230,.26);
  transform:rotate(45deg);transition:border-color .2s var(--ease);}
.cm-step.done + .cm-step:not(.cm-step-extra)::before{border-right-color:#c8ff00;border-top-color:#c8ff00;}
.cm-step.on{color:#c8ff00;}
.cm-step.on .kri{transform:scale(1.14);}
.cm-step.on::after{content:'';position:absolute;left:50%;bottom:-4px;transform:translateX(-50%);
  width:20px;height:3px;border-radius:2px;background:#c8ff00;}
.cm-step.pub{color:#c8ff00;opacity:.85;}                      /* 저장 — 돈이 걸린 곳은 눈에 띄어야 한다 */
.cm-step.pub.on{opacity:1;}
/* 지금 레이아웃이 안 쓰는 단계(영문·강조) · 아직 글자를 안 고른 '글자' — 흐리게.
   ⛔ 누르는 것 자체는 막지 않는다(왜 비었는지 시트에서 읽어야 하므로). */
.cm-step.na{opacity:.34;}
.cm-step.na.on{opacity:1;}
/* '저장' 오른쪽 홈앱 아이콘 — 단계가 아니라 별도 도구. 왼쪽에 얇은 구분선으로 도구 줄과 살짝 떼어 놓는다. */
.cm-step.cm-step-extra::before{content:'';position:absolute;left:0;top:22%;bottom:22%;width:1px;background:var(--line,#2c2b26);}
.cm-step.cm-step-extra:active{color:#c8ff00;}
/* ── 기능이 많은 단계의 가로 버튼 줄 (머리글 · 박스 · 로고 · 색상) ──
   기능 이름을 알약으로 한 줄에 깔고 고른 것 하나만 밑에 보여 준다 → 시트가 473px → 150px 안팎.
   ⛔ 슬라이드(페이저)가 아니라 버튼이다(사장님 지시) — 무엇이 있는지 한눈에 보여야 하고,
      시트를 좌우로 미는 '단계 넘김'과 부딪히지 않아야 한다. */
.cm-subrail{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
  padding:0 0 9px;margin:0 0 10px;border-bottom:1px solid var(--line);}
.cm-subrail::-webkit-scrollbar{display:none;}
.cm-sub{flex:0 0 auto;font-family:inherit;font-size:clamp(15px,3.9vw,18px);font-weight:700;white-space:nowrap;
  background:var(--panel2);border:1px solid var(--line);color:var(--body,#c2bdb0);
  border-radius:999px;padding:8px 14px;cursor:pointer;transition:.14s var(--ease);}
.cm-sub.on{background:#c8ff00;border-color:#c8ff00;color:#0a0a09;}
.cm-page{display:none;}
.cm-page.on{display:block;}
/* 빈 시트 대신 한 줄 안내 — 아무것도 없으면 "고장난 줄" 안다 */
.cm-na{font-size:22px;line-height:1.5;color:var(--body,#c2bdb0);
  background:rgba(200,255,0,.05);border:1px solid rgba(200,255,0,.25);border-radius:12px;padding:12px 14px;}
/* 입력 중(키보드) — 라벨을 접어 줄을 낮춘다 */
body.cnapp.kr-typing .cm-step .l{display:none;}
body.cnapp.kr-typing .cm-step{width:54px;min-height:44px;padding:4px 2px;}
body.cnapp.kr-typing .cm-rail{padding-top:5px;padding-bottom:calc(5px + env(safe-area-inset-bottom));}
/* 오른쪽에 단계가 더 있다는 걸 알려 준다 — 안 그러면 화면 끝에서 끝난 줄 안다 */
.cm-rail-fade{position:absolute;right:0;bottom:0;width:34px;pointer-events:none;z-index:4;
  top:auto;height:calc(100% - 1px);
  background:linear-gradient(to right, rgba(22,21,18,0), var(--panel));}
body.cnapp.rail-end .cm-rail-fade{opacity:0;transition:opacity .2s;}

/* ---- 확인 팝업(우리 디자인) ---- */
#confirmModal{z-index:120;}
/* ⛔ max-height·overflow 를 지우지 말 것 — #payModal 이 이 칸을 쓴다(index.html).
     결제 패널은 연락처·동의·약관링크가 아래로 쌓이는 폼이고 글자가 22px 이라,
     이게 없으면 짧은 화면에서 잘려 「결제하고 저장」 버튼이 사라진다(2026-08-10). */
.confirm-card{background:var(--panel);border:1px solid var(--line);border-radius:18px;
  width:min(440px,92vw);padding:28px 26px 24px;text-align:center;
  max-height:88vh;overflow-y:auto;overscroll-behavior:contain;
  box-shadow:0 30px 90px rgba(0,0,0,.6);transform:translateY(12px) scale(.98);transition:transform .24s var(--ease);}
#confirmModal.show .confirm-card{transform:none;}
.confirm-title{font-size:26px;font-weight:800;margin-bottom:10px;}
.confirm-msg{color:var(--mut);font-size:22px;line-height:1.55;margin-bottom:22px;}
.confirm-btns{display:flex;gap:10px;}
.confirm-btns .btn{margin-top:0;}
/* 금액 칸 — 누르는 단추 바로 옆에 붙여 「무엇을 얼마에」가 한눈에 들어오게 한다 (2026-08-11).
   ⛔ 22px 아래로 내리지 않는다(결제 화면 글자 규칙).
   ⛔ payline 이 남은 자리를 다 먹게 둔다 — 안 그러면 취소 단추와 폭이 어긋난다. */
.confirm-btns .payline{display:flex;gap:8px;align-items:stretch;flex:1;min-width:0;}
/* ⛔ 단추가 먼저 줄어들고 금액은 안 줄어든다 — 좁은 폰에서 금액이 잘리면 그게 제일 나쁘다 */
.confirm-btns .payline .btn{flex:1 1 auto;min-width:0;}
.payamt{display:flex;align-items:center;padding:0 14px;border-radius:10px;
  border:1px solid var(--line);background:var(--panel2);color:var(--ink);
  font-size:22px;font-weight:800;white-space:nowrap;font-variant-numeric:tabular-nums;}
