/* LILT 콘솔/대시보드 공통 스타일 — 깔끔하고 입력이 편한 폼 중심 UI */
/* 네오고딕 계열 UI 폰트 (self-hosted, 외부 의존 없음) */
@font-face{
  font-family:'Pretendard';
  src:url('fonts/PretendardVariable.woff2') format('woff2-variations');
  font-weight:45 920; font-style:normal; font-display:swap;
}
:root{
  --bg:#f2f7fc; --card:#ffffff; --ink:#2b3340; --soft:#727a88; --faint:#a3adbd;
  --line:#e7eef6; --cobalt:#7cbceb; --cobalt-deep:#4c93d6;
  --sw-on:rgba(0,122,255,.5);       /* 토글 켜짐 — 악센트 블루 반투명 유리 */
  --sw-off:rgba(120,120,128,.14);   /* 토글 꺼짐 — 무채색 유리 */
  --cobalt-soft:#f0f8fe; --baby:#d5eafb; --danger:#dc8582; --ok:#5bb695;
  --radius:14px; --shadow:0 8px 26px rgba(120,170,225,.10);
  --sans:'Pretendard','Apple SD Gothic Neo','Malgun Gothic',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
}
*{box-sizing:border-box}
html,body{margin:0}
body{ background:var(--bg); color:var(--ink); font-family:var(--sans);
  -webkit-font-smoothing:antialiased; line-height:1.6; font-size:15px; }
a{color:var(--cobalt-deep)}

.topbar{ position:sticky; top:0; z-index:10; background:rgba(255,255,255,.9);
  backdrop-filter:blur(8px); border-bottom:1px solid var(--line);
  display:flex; align-items:center; justify-content:space-between; padding:14px 20px; }
.brand{ font-weight:800; letter-spacing:.32em; color:var(--cobalt); text-indent:.32em; font-size:15px; }
/* logo.png 은 1254x1254 정사각 캔버스에 잉크(별+워드마크)가 가로 59% / 세로 53% 만 차지하고
   나머지는 투명 여백이다. 그래서 박스를 키운 뒤 여백만큼 음수 마진으로 상쇄한다
   → 화면에는 크게, 레이아웃은 잉크 크기만큼만 차지.
   잉크 세로 50px 기준: 박스 94px, 상하 여백 (94-50)/2 = 22px */
.brand-img{
  height:94px; width:auto; display:block;
  margin-top:-22px; margin-bottom:-22px;
  margin-left:-12px; margin-right:-12px;
}
.topbar .who{ font-size:13px; color:var(--soft); display:flex; align-items:center; gap:6px; }
.topbar .who b{ color:var(--ink); font-weight:700; }
.logout{ font-size:13px; color:var(--soft); text-decoration:none; }
.logout:hover{ color:var(--danger); }

.wrap{ max-width:760px; margin:0 auto; padding:22px 16px 60px; }
.pagehead{ margin:8px 4px 20px; }
.pagehead h1{ font-size:22px; margin:0 0 4px; letter-spacing:-.01em; }
.pagehead p{ margin:0; color:var(--soft); font-size:14px; }

.card{ background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:22px; margin-bottom:18px; }
.card > h2{ font-size:15px; margin:0 0 4px; display:flex; align-items:center; gap:8px; }
.card > .desc{ color:var(--soft); font-size:13px; margin:0 0 18px; }
.card > h2 .badge{ font-size:11px; font-weight:700; padding:2px 9px; border-radius:999px;
  background:var(--cobalt-soft); color:var(--cobalt-deep); letter-spacing:.02em; }

.field{ margin-bottom:22px; }
/* 폼 내 소섹션 구분 헤딩(예: 오시는 길) */
.group-head{ font-size:12px; font-weight:800; color:var(--cobalt-deep); letter-spacing:.06em;
  margin:28px 0 14px; padding-bottom:8px; border-bottom:1px solid var(--line); }
.field:last-child{ margin-bottom:0; }
.field label{ display:block; font-size:13px; font-weight:600; color:var(--ink); margin-bottom:7px; }
.field .hint{ font-weight:400; color:var(--faint); }
.field input, .field select, .field textarea{
  width:100%; padding:12px 14px; border:1px solid var(--line); border-radius:11px;
  background:#fcfdff; font-family:inherit; font-size:16px; color:var(--ink); transition:.15s; }
/* iOS Safari 포커스 자동확대 방지: 모든 텍스트 입력 16px 이상 */
input[type=text], input[type=tel], input[type=password], input[type=search], input:not([type]), textarea, select{ font-size:16px; }
.field textarea{ resize:vertical; min-height:96px; }
.field input:focus, .field select:focus, .field textarea:focus{
  outline:none; border-color:var(--cobalt); box-shadow:0 0 0 3px rgba(58,95,176,.12); background:#fff; }
.row{ display:flex; gap:12px; margin-bottom:20px; }
.row > *{ flex:1; min-width:0; }
.row .field{ margin-bottom:0; }
@media (max-width:520px){ .row{ flex-direction:column; gap:15px; } }

.choice{ display:flex; gap:10px; }
.choice label{ flex:1; margin:0; cursor:pointer; position:relative; }
.choice input{ position:absolute; opacity:0; }
.choice .opt{ display:block; padding:13px 14px; border:1.5px solid var(--line); border-radius:12px;
  text-align:center; font-weight:600; font-size:14px; color:var(--soft); transition:.15s; background:#fcfdff; }
.choice .opt small{ display:block; font-weight:400; font-size:12px; color:var(--faint); margin-top:3px; }
.choice input:checked + .opt{ border-color:var(--cobalt); color:var(--cobalt-deep); background:var(--cobalt-soft); }

.btn{ display:inline-flex; align-items:center; justify-content:center; gap:8px; cursor:pointer;
  padding:12px 20px; border-radius:11px; border:1px solid transparent; font-family:inherit;
  font-size:14px; font-weight:700; text-decoration:none; transition:.15s; white-space:nowrap; }
.btn-primary{ background:var(--cobalt); color:#fff; }
.btn-primary:hover{ background:var(--cobalt-deep); }
.btn-ghost{ background:#fff; color:var(--cobalt-deep); border-color:var(--line); }
.btn-ghost:hover{ border-color:var(--cobalt); }
.btn-danger{ background:#fff; color:var(--danger); border-color:#f0d7d7; }
.btn-block{ width:100%; }
.btn-sm{ padding:8px 13px; font-size:13px; font-weight:600; }
.actions{ display:flex; gap:10px; margin-top:20px; }

.flash{ padding:12px 16px; border-radius:11px; font-size:14px; margin-bottom:18px; font-weight:600; }
.flash-ok{ background:#e7f6ee; color:var(--ok); border:1px solid #c9ecd8; }
.flash-err{ background:#fbeaea; color:var(--danger); border:1px solid #f3d4d4; }

.pill{ display:inline-block; padding:3px 10px; border-radius:999px; font-size:12px; font-weight:700; }
.pill-on{ background:#e7f6ee; color:var(--ok); }
.pill-off{ background:#eef0f4; color:var(--soft); }

.list{ display:flex; flex-direction:column; gap:10px; }
.item{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:14px 16px; border:1px solid var(--line); border-radius:12px; background:#fcfdff; }
.item .meta{ min-width:0; }
.item .t{ font-weight:700; font-size:14px; display:flex; align-items:center; gap:8px; }
.item .s{ font-size:12px; color:var(--soft); margin-top:2px; word-break:break-all; }
.item .grow{ flex:1; }
.item > form{ flex:none; }
.item > form .btn{ width:100%; }
/* 계좌 스테이징(전체 저장 전) 상태 */
.item.staged-add{ border-style:dashed; border-color:var(--cobalt); background:var(--cobalt-soft); }
.item.staged-del{ opacity:.55; }
.item.staged-del .t, .item.staged-del .s{ text-decoration:line-through; }
.stage-tag{ font-size:11px; font-weight:700; color:var(--cobalt-deep); background:#fff;
  border:1px solid var(--baby); border-radius:999px; padding:1px 7px; }
.acct-add{ border-top:1px dashed var(--line); margin-top:6px; padding-top:14px; }
.inline-form{ display:flex; gap:8px; align-items:center; }
.inline-form select{ padding:8px 10px; border:1px solid var(--line); border-radius:9px; background:#fff; font-size:13px; }

.empty{ text-align:center; padding:34px 16px; color:var(--soft); }
.empty .big{ font-size:15px; font-weight:700; color:var(--ink); margin-bottom:6px; }

.preview-link{ display:inline-flex; align-items:center; gap:6px; font-size:13px; font-weight:600; }
.muted{ color:var(--faint); font-size:12px; }

/* 클릭 가능한 리스트 항목(고객 행) */
.item.clickable{ cursor:pointer; transition:.15s; }
.item.clickable:hover{ border-color:var(--cobalt); background:#fff; box-shadow:0 4px 14px rgba(43,71,136,.06); }
.item .chev{ color:var(--faint); font-size:18px; flex:none; }
/* 순서 이동 — 테두리 박스가 그대로 드러나 행마다 화살표 버튼 두 개가 대놓고 붙어 보였다.
   박스와 배경을 걷어내고 평소에는 흐리게 두었다가, 그 행에 마우스가 올라오거나
   키보드 포커스가 들어올 때만 또렷해지게 한다. 기능·마크업은 그대로다. */
.acct-move{ display:flex; flex-direction:column; gap:0; flex:none; margin-right:-2px;
  opacity:.26; transition:opacity .15s; }
.item:hover .acct-move,
.item:focus-within .acct-move{ opacity:1; }
.acct-move__btn{ display:flex; align-items:center; justify-content:center; width:20px; height:15px;
  border:none; border-radius:5px; background:none; color:var(--faint);
  font-size:9px; line-height:1; cursor:pointer; padding:0; transition:.12s; }
.acct-move__btn:hover{ color:var(--cobalt-deep); background:var(--cobalt-soft); }
.acct-move__btn:focus-visible{ outline:2px solid var(--cobalt); outline-offset:1px; }
/* 터치 기기에는 hover 가 없어 흐린 채로 남는다 — 항상 보이게 둔다. */
@media (hover:none){ .acct-move{ opacity:.75; } }
.item.staged-del .acct-move__btn{ pointer-events:none; opacity:.5; }

/* 모달(팝업) */
.modal{ display:none; position:fixed; inset:0; z-index:50; align-items:center; justify-content:center; padding:18px; }
.modal.open{ display:flex; }
.modal__backdrop{ position:absolute; inset:0; background:rgba(30,42,66,.42); }
.modal__box{ position:relative; width:100%; max-width:440px; max-height:88vh; overflow:auto;
  background:var(--card); border-radius:16px; box-shadow:0 24px 70px rgba(20,35,70,.32); }
.modal__head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
  padding:20px 22px 14px; border-bottom:1px solid var(--line); position:sticky; top:0; background:var(--card); }
.modal__title{ font-size:17px; font-weight:800; }
.modal__sub{ font-size:12px; color:var(--soft); margin-top:3px; }
.modal__x{ flex:none; width:30px; height:30px; border:none; border-radius:8px; background:#f2f4f8;
  color:var(--soft); font-size:14px; cursor:pointer; }
.modal__x:hover{ background:#e8ebf2; color:var(--ink); }
.modal__body{ padding:18px 22px; }
.modal__foot{ padding:14px 22px 20px; display:flex; align-items:center; gap:8px; border-top:1px solid var(--line); }
.modal__foot form{ margin:0; display:inline-flex; }
.modal__foot .btn{ height:38px; padding:0 15px; font-size:13px; font-weight:600; white-space:nowrap; }
.modal__foot .del-form{ margin-left:auto; }

.info-row{ display:flex; align-items:flex-start; gap:12px; padding:9px 0; border-bottom:1px dashed var(--line); }
.info-row:last-child{ border-bottom:none; }
.info-row .k{ flex:none; width:78px; color:var(--soft); font-size:13px; }
.info-row .v{ flex:1; font-size:14px; color:var(--ink); word-break:break-all; white-space:pre-line; }
.info-empty{ text-align:center; color:var(--soft); padding:26px 10px; font-size:14px; }

/* 핸드폰 3칸 입력 */
.phone-3{ display:flex; align-items:center; gap:8px; }
.phone-3 input{ flex:1; min-width:0; text-align:center; letter-spacing:.05em; }
.phone-3 input[data-phone="1"]{ flex:0 0 74px; }
.phone-3 .sep{ flex:none; color:var(--faint); }

/* ── 전반 다듬기 ── */
.card{ border-radius:18px; padding:24px 24px 26px; box-shadow:0 8px 30px rgba(43,71,136,.06); }
.card > h2{ font-size:16px; font-weight:800; margin:0 0 5px; letter-spacing:-.01em; }
.pagehead h1{ font-size:23px; font-weight:800; }
.btn{ border-radius:11px; }

/* 접기(혼주 정보 등) */
.foldable{ border:1px solid var(--line); border-radius:13px; padding:0 15px; margin-bottom:16px; background:#fbfcff; }
.foldable > summary{ cursor:pointer; padding:14px 0; font-size:14px; font-weight:600; color:var(--ink);
  list-style:none; display:flex; align-items:center; gap:9px; }
.foldable > summary::-webkit-details-marker{ display:none; }
.foldable > summary::before{ content:"+"; color:var(--cobalt); font-weight:800; font-size:16px; width:14px; text-align:center; }
.foldable[open] > summary::before{ content:"\2013"; }
.fold-body{ padding:2px 0 14px; }
.subhead{ font-size:12px; font-weight:800; color:var(--cobalt-deep); letter-spacing:.06em; margin:14px 0 8px; }
.fold-body .subhead:first-child{ margin-top:2px; }

/* 혼주(부모) 접기 — 신랑/신부 각 1줄 */
.fold-details{ margin-top:8px; margin-bottom:16px; border:1px solid var(--line); border-radius:12px; background:#fcfdff; }
.fold-details > summary{ cursor:pointer; padding:12px 14px; font-weight:600; font-size:13.5px; color:var(--soft);
  list-style:none; display:flex; align-items:center; justify-content:space-between; gap:8px; }
.fold-details > summary::-webkit-details-marker{ display:none; }
.fold-details > summary::after{ content:"\25BE"; color:var(--faint); font-size:12px; transition:transform .2s ease; }
.fold-details[open] > summary::after{ transform:rotate(180deg); }
.fold-details[open] > summary{ border-bottom:1px solid var(--line); }
.fold-details .fold-body{ padding:12px 14px 14px; }
.parent-group{ margin-bottom:15px; }
.parent-group:last-child{ margin-bottom:0; }
.parent-group__label{ font-size:12.5px; font-weight:700; color:var(--ink); margin-bottom:7px; }
.parent-group__row{ display:flex; gap:8px; margin-bottom:8px; }
.parent-group input{ width:100%; min-width:0; padding:10px 11px; border:1px solid var(--line); border-radius:9px;
  background:#fff; font-family:inherit; font-size:16px; color:var(--ink); transition:.15s; }
.parent-group__row input{ flex:1; }
.parent-group input:focus{ outline:none; border-color:var(--cobalt); box-shadow:0 0 0 3px rgba(58,95,176,.12); }

/* 대중교통 안내(여러 개) — 폰에서 넓게 쓰도록 설명 입력은 한 줄 전체 */
.transit-list{ display:flex; flex-direction:column; gap:7px; margin-bottom:9px; }
.transit-list:empty{ display:none; }
.transit-row{ display:flex; align-items:flex-start; gap:9px; padding:10px 12px; border:1px solid var(--line); border-radius:10px; background:#fcfdff; }
/* 분류 라벨은 글자 수(버스 2 ~ 셔틀버스 4)에 따라 폭이 달라져 뒤따르는 내용 텍스트의
   시작점이 행마다 어긋났다. 라벨 폭을 고정해 내용의 좌측 정렬선을 하나로 맞춘다. */
.transit-row__type{ flex:none; margin-top:1px; font-size:11.5px; font-weight:800; color:var(--cobalt-deep); background:var(--cobalt-soft); border-radius:999px; padding:2px 9px;
  display:inline-flex; align-items:center; justify-content:center; width:70px; white-space:nowrap; }
.transit-row__desc{ flex:1; min-width:0; font-size:13.5px; color:var(--ink); word-break:break-word; line-height:1.5; }
.transit-row__x{ flex:none; width:24px; height:24px; border:none; border-radius:50%; background:rgba(20,28,45,.5); color:#fff; font-size:13px; line-height:1; cursor:pointer; }
.transit-add{ display:flex; flex-direction:column; gap:8px; }
.transit-add__row{ display:flex; gap:8px; }
.transit-add__row select{ flex:none; width:120px; }
.transit-add__row .btn{ flex:none; }
/* ⚠ 120px 셀렉트 + 입력 + 버튼은 360px 화면에서 20px 넘친다(2026-09-01 계측).
   좁아지면 줄을 바꿔 셀렉트와 버튼이 한 줄을 나눠 갖게 한다. */
@media (max-width:420px){
  .transit-add__row{ flex-wrap:wrap; }
  .transit-add__row select{ flex:1 1 auto; width:auto; min-width:0; }
  .transit-add__row .btn{ flex:none; }
}
.transit-add > input{ width:100%; }

/* 방명록 목록 페이징 — 편집 페이지 모달이 대시보드 카드로 옮겨 가면서(2026-08-28)
   모달 전용 규칙(#guestbookModal · #gbManageList)은 지웠고 페이저만 남겨 재사용한다. */
.gb-mpager{ display:flex; align-items:center; justify-content:center; gap:14px; }
.gb-mpager:empty{ display:none; }
.gb-mpg{ width:34px; height:34px; border-radius:50%; border:1px solid var(--line); background:#fff; color:var(--cobalt-deep); font-size:16px; line-height:1; cursor:pointer; }
.gb-mpg:disabled{ color:var(--faint); opacity:.5; cursor:default; }
.gb-mpg-info{ font-size:13px; color:var(--soft); }

/* 초대 문구 추천 칩 */
.preset-row{ display:flex; flex-wrap:wrap; gap:7px; margin-bottom:11px; }
.preset-btn{ padding:7px 13px; border:1px solid var(--line); border-radius:999px; background:#fff;
  font-family:inherit; font-size:12.5px; color:var(--soft); cursor:pointer; transition:.15s; }
.preset-btn:hover{ border-color:var(--cobalt); color:var(--cobalt-deep); background:#fbfcff; }
.preset-clear{ color:var(--cobalt-deep); border-color:var(--cobalt-soft); background:var(--cobalt-soft); font-weight:700; }

/* 토글 스위치 */
.switch-row{ display:flex; align-items:center; justify-content:space-between; padding:15px 2px;
  border-bottom:1px solid var(--line); margin:0; cursor:pointer; }
.switch-label{ font-weight:700; font-size:15px; color:var(--ink); }
/* iOS 토글 — 51×31 트랙에 27px 노브(실제 iPhone 비율).
   불투명 컬러 대신 반투명 유리: 트랙이 뒤를 비추고, 테두리 하이라이트로 두께를 만든다. */
.switch{ position:relative; display:inline-block; width:51px; height:31px; flex:none; }
.switch input{ position:absolute; opacity:0; width:0; height:0; }
.switch .slider{
  position:absolute; inset:0; border-radius:999px;
  background:var(--sw-off);
  -webkit-backdrop-filter:blur(12px) saturate(160%); backdrop-filter:blur(12px) saturate(160%);
  box-shadow:inset 0 .5px 0 rgba(255,255,255,.7), inset 0 0 0 .5px rgba(38,45,56,.09);
  transition:background .28s var(--ease-ios, cubic-bezier(.32,.72,0,1)),
             box-shadow .28s var(--ease-ios, cubic-bezier(.32,.72,0,1));
}
.switch .slider::before{
  content:""; position:absolute; width:27px; height:27px; left:2px; top:2px; border-radius:50%;
  background:linear-gradient(180deg, rgba(255,255,255,.98), rgba(255,255,255,.86));
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  box-shadow:0 2px 6px rgba(38,45,56,.16), 0 0 0 .5px rgba(38,45,56,.06),
             inset 0 .5px 0 rgba(255,255,255,.9);
  transition:transform .28s var(--ease-ios, cubic-bezier(.32,.72,0,1));
}
.switch input:checked + .slider{
  background:var(--sw-on);
  box-shadow:inset 0 .5px 0 rgba(255,255,255,.55), inset 0 0 0 .5px rgba(0,122,255,.3),
             0 1px 8px rgba(0,122,255,.16);
}
.switch input:checked + .slider::before{ transform:translateX(20px); }
.switch input:focus-visible + .slider{ box-shadow:var(--acc-glow, 0 0 0 3px rgba(0,122,255,.16)); }

/* 옵션 설정 블록 */
.opt-block{ padding:14px 2px 6px; }
.sub-upload{ border-top:1px dashed var(--line); margin-top:8px; padding-top:16px; }

/* 이미지 썸네일 / 갤러리 */
.thumb-row{ margin-bottom:12px; }
/* 좁은 화면은 3열. 넓어지면 칸 수가 늘어나 썸네일이 커지지 않는다(2026-08-31 지적) — 
   3열 고정이면 편집 컬럼이 760px 까지 넓어질 때 한 장이 240px 넘게 부풀었다. */
.gallery-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; margin-bottom:14px; }
.thumb{ position:relative; border-radius:11px; overflow:hidden; background:#eef1f6; border:1px solid var(--line); aspect-ratio:1/1; }
.thumb.thumb-wide{ aspect-ratio:16/10; max-width:340px; }
.thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
.thumb-del{ position:absolute; top:5px; right:5px; margin:0; }
.thumb-x{ width:24px; height:24px; border:none; border-radius:50%; background:rgba(20,28,45,.6);
  color:#fff; font-size:12px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; }
.thumb-x:hover{ background:rgba(192,69,69,.92); }
/* 첫 화면 대표 사진 선택 */
.thumb .hero-pick{ position:absolute; left:50%; bottom:6px; transform:translateX(-50%); z-index:3;
  font-size:10.5px; font-weight:800; line-height:1; padding:4px 9px; border-radius:999px; cursor:pointer;
  border:1px solid var(--cobalt-deep); background:rgba(255,255,255,.92); color:var(--cobalt-deep); white-space:nowrap; }
.thumb .hero-pick:hover{ background:#fff; }
.thumb.is-hero{ border-color:var(--cobalt-deep); box-shadow:inset 0 0 0 2px var(--cobalt-deep); }
.thumb.is-hero .hero-pick{ background:var(--cobalt-deep); color:#fff; }
.thumb.is-hero .hp-txt::after{ content:' ✓'; }

/* 업로드 폼 */
.upload-form input[type=file]{ display:block; width:100%; font-size:13px; color:var(--soft); margin-bottom:10px; }
.upload-form input[type=file]::file-selector-button{ margin-right:10px; padding:9px 14px; border:1px solid var(--line);
  border-radius:9px; background:#fff; color:var(--cobalt-deep); font-weight:700; cursor:pointer; }
.preview-strip{ display:flex; flex-wrap:wrap; gap:8px; }
.preview-strip:empty{ display:none; }
.preview-strip .pv{ width:64px; height:64px; object-fit:cover; border-radius:9px; border:1px solid var(--line); margin-bottom:10px; }
/* 새 사진 미리보기에서 대표 지정 */
.pv-wrap{ position:relative; width:64px; margin-bottom:10px; }
.pv-wrap .pv{ margin-bottom:0; width:64px; height:64px; }
.pv-wrap .pv-hero{ position:absolute; left:50%; bottom:4px; transform:translateX(-50%); z-index:2;
  font-size:10px; font-weight:800; line-height:1; padding:3px 7px; border-radius:999px; cursor:pointer; white-space:nowrap;
  border:1px solid var(--cobalt-deep); background:rgba(255,255,255,.92); color:var(--cobalt-deep); }
.pv-wrap.is-hero .pv{ outline:2px solid var(--cobalt-deep); outline-offset:0; }
.pv-wrap.is-hero .pv-hero{ background:var(--cobalt-deep); color:#fff; }

/* ── 버튼 리스타일 (플랫 · 그라데이션/무거운 그림자 제거) ── */
.btn{ border-radius:11px; font-weight:600; letter-spacing:.01em; transition:transform .12s ease, background .15s, border-color .15s; }
.btn:active{ transform:translateY(1px); }
.btn-primary{ background:var(--cobalt); color:#fff; border:none; }
.btn-primary:hover{ background:var(--cobalt-deep); }
.btn-ghost{ background:#fff; color:var(--cobalt-deep); border:1px solid var(--line); }
.btn-ghost:hover{ border-color:var(--cobalt); background:var(--cobalt-soft); }
.btn-danger{ background:#fff; color:var(--danger); border:1px solid #efdad9; }
.btn-danger:hover{ background:#fdf5f5; border-color:#e6b9b7; }
.btn-sm{ border-radius:9px; }
.btn-block{ width:100%; }

/* ── 모달 애니메이션 ── */
.modal.open .modal__backdrop{ animation:liltFade .22s ease both; }
.modal.open .modal__box{ animation:liltPop .34s cubic-bezier(.2,1.05,.32,1) both; }
@keyframes liltFade{ from{opacity:0} to{opacity:1} }
@keyframes liltPop{ 0%{opacity:0; transform:translateY(14px) scale(.9);} 60%{opacity:1;} 100%{opacity:1; transform:translateY(0) scale(1);} }

/* 그려지는 체크 / 흔들리는 ! */
.alert-check{ width:60px; height:60px; margin:0 auto 16px; display:block; }
.alert-check .ac-ring{ stroke:var(--ok); stroke-width:2; fill:rgba(91,182,149,.08);
  stroke-dasharray:170; stroke-dashoffset:170; animation:acRing .5s ease forwards; }
.alert-check .ac-tick{ stroke:var(--ok); stroke-width:2.4; fill:none; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:64; stroke-dashoffset:64; animation:acTick .34s .42s ease forwards; }
.alert-check.err .ac-ring{ stroke:var(--danger); fill:rgba(213,115,111,.10); }
.alert-check.err .ac-tick{ stroke:var(--danger); }
@keyframes acRing{ to{stroke-dashoffset:0} }
@keyframes acTick{ to{stroke-dashoffset:0} }
.alert-err-shake{ animation:acShake .5s .1s ease; }
@keyframes acShake{ 0%,100%{transform:translateX(0)} 20%{transform:translateX(-6px)} 40%{transform:translateX(6px)} 60%{transform:translateX(-4px)} 80%{transform:translateX(4px)} }

/* ── 하단 푸터 ── */
.site-foot{ text-align:center; padding:34px 20px 46px; color:var(--faint); }
.site-foot .insta{ display:inline-flex; align-items:center; gap:7px; color:var(--soft);
  text-decoration:none; font-size:13px; font-weight:600; padding:7px 14px; border:1px solid var(--line);
  border-radius:999px; background:#fff; transition:.15s; }
.site-foot .insta:hover{ border-color:var(--cobalt); color:var(--cobalt-deep); }
.site-foot .insta svg{ width:15px; height:15px; }
.site-foot .copy{ margin-top:14px; font-size:12px; color:var(--faint); letter-spacing:.02em; }

/* 앨범 유형 미리보기 */
.gtype-row{ display:flex; gap:9px; margin-bottom:6px; }
.gtype{ flex:1; cursor:pointer; position:relative; }
.gtype input{ position:absolute; width:0; height:0; opacity:0; margin:0; }
.gtype .gt-card{ display:block; border:1.5px solid var(--line); border-radius:12px; padding:10px 8px; text-align:center; background:#fcfdff; transition:.15s; }
.gtype .gt-name{ display:block; }
.gtype input:checked + .gt-card{ border-color:var(--cobalt); background:var(--cobalt-soft); }
.gt-prev{ display:block; height:38px; margin-bottom:7px; overflow:hidden; }
.gt-prev i{ display:block; background:#c7d8f2; border-radius:3px; }
/* 썸네일 격자 */
.gt-grid{ display:grid; grid-template-columns:repeat(3,1fr); grid-template-rows:repeat(3,1fr); gap:3px; height:100%; }
.gt-grid i{ height:100%; }
/* 비정형(3×3 그리드에 행 스팬으로 배치 → 카드 밖으로 넘치지 않음) */
.gt-mason{ display:grid; grid-template-columns:repeat(3,1fr); grid-template-rows:repeat(3,1fr); gap:3px; height:100%; }
.gt-mason i{ height:auto; }
.gt-mason i:nth-child(1){ grid-column:1; grid-row:1/3 }
.gt-mason i:nth-child(2){ grid-column:1; grid-row:3 }
.gt-mason i:nth-child(3){ grid-column:2; grid-row:1 }
.gt-mason i:nth-child(4){ grid-column:2; grid-row:2/4 }
.gt-mason i:nth-child(5){ grid-column:3; grid-row:1 }
.gt-mason i:nth-child(6){ grid-column:3; grid-row:2/4 }
/* 슬라이드(큰 사진 + 옆 사진이 살짝 보이는 캐러셀 느낌, 넘침은 클립) */
.gt-slide{ display:flex; gap:3px; height:100%; }
.gt-slide i{ height:100%; flex:0 0 22%; }
.gt-slide i:nth-child(1){ flex:0 0 68% }
.gt-name{ font-size:12px; font-weight:700; color:var(--ink); }
.gtype input:checked + .gt-card .gt-name{ color:var(--cobalt-deep); }


/* ── 얼럿·확인 모달 ──
   ⚠ 대시보드의 .btn-primary 는 유리(반투명 + backdrop-blur) 버튼이라 흰 모달 위에 얹으면
     거의 보이지 않는다(2026-08-31 지적). 모달 안에서만 불투명하게 되돌린다. */
.alert-box{ max-width:320px; padding:24px 22px 20px; text-align:center; }
.alert-msg{ font-size:15.5px; font-weight:700; color:var(--ink); margin-bottom:18px; line-height:1.55; }
.alert-sub{ font-size:13px; font-weight:400; color:var(--soft); line-height:1.6;
  margin:-12px 0 18px; white-space:pre-line; }
.alert-box .btn{ height:44px; font-size:14.5px; font-weight:700; border-radius:12px; }
.alert-box .btn-primary,
.alert-box .btn-primary:hover,
.alert-box .btn-primary:active{
  background:var(--cobalt-deep); color:#fff;
  -webkit-backdrop-filter:none; backdrop-filter:none;
  box-shadow:0 4px 12px rgba(76,147,214,.28);
}
.alert-box .btn-primary::before,
.alert-box .btn-primary::after{ display:none; }
.alert-box .btn-primary:hover{ background:#3f83c4; }
/* 확인 모달 — 두 버튼을 나란히. 취소가 왼쪽(무게가 가벼운 쪽) */
.alert-actions{ display:flex; gap:8px; }
.alert-actions .btn{ flex:1 1 0; }
.alert-box .btn-ghost{ background:#fff; color:var(--soft); border:1px solid var(--line); }
.alert-box .btn-ghost:hover{ border-color:var(--cobalt); color:var(--cobalt-deep); }

/* ═══════════════ 고객 검색 + 페이징(운영자) ═══════════════ */
.search-box{ position:relative; margin-bottom:14px; }
.search-box svg{ position:absolute; left:14px; top:50%; transform:translateY(-50%);
  width:18px; height:18px; color:var(--faint); pointer-events:none; }
.search-box input{ width:100%; padding:12px 14px 12px 42px; border:1.5px solid var(--line);
  border-radius:12px; font:inherit; background:#fcfdff; color:var(--ink); }
.search-box input:focus{ outline:none; border-color:var(--cobalt); box-shadow:0 0 0 3px var(--cobalt-soft); }
.pager{ display:flex; align-items:center; justify-content:center; gap:14px; margin-top:14px; }
.pg-btn{ border:1.5px solid var(--line); background:#fff; color:var(--cobalt-deep);
  border-radius:10px; padding:8px 14px; font:inherit; font-weight:600; cursor:pointer; transition:.15s; }
.pg-btn:hover:not(:disabled){ border-color:var(--cobalt); background:var(--cobalt-soft); }
.pg-btn:disabled{ color:var(--faint); cursor:default; opacity:.5; }
.pg-info{ font-size:14px; color:var(--soft); }
.pg-info b{ color:var(--ink); }

/* ═══════════════ 슬러그(공개 주소) 편집 ═══════════════ */
.slug-edit{ margin-top:16px; padding-top:16px; border-top:1px dashed var(--line); }
.slug-lab{ font-size:13px; font-weight:700; color:var(--ink); margin-bottom:9px; }
.slug-lab .hint{ font-weight:400; color:var(--faint); font-size:12px; }
.slug-input{ display:flex; align-items:stretch; border:1.5px solid var(--line);
  border-radius:11px; overflow:hidden; background:#fcfdff; }
.slug-input:focus-within{ border-color:var(--cobalt); box-shadow:0 0 0 3px var(--cobalt-soft); }
.slug-prefix{ display:flex; align-items:center; padding:0 12px; background:transparent;
  color:var(--faint); font-size:13px; border-right:1px solid var(--line); white-space:nowrap; }
.slug-field{ flex:1; border:none; outline:none; background:transparent; padding:11px 12px;
  font:inherit; color:var(--ink); min-width:0; }
.slug-msg{ font-size:12.5px; min-height:1em; }
.slug-msg.ok{ color:var(--ok); }
.slug-msg.err{ color:var(--danger); }
.slug-msg.neutral{ color:var(--faint); }

/* ═══════════════ 예식 일시 선택기(캘린더) ═══════════════ */

/* ═══ 예식 일시 선택기 — 톤·짜임 재정비(2026-08-31) ═══
   ⚠ 앞서 iOS 블루(--acc #007aff)를 그대로 썼더니 선택한 날짜만 형광으로 튀어
     대시보드의 파스텔 톤에서 혼자 겉돌았다. 강조는 --cobalt 계열로 되돌린다.
   ⚠ 날짜 칸에 aspect-ratio:1 을 주면 컬럼이 넓어질수록 칸이 정사각으로 커져
     캘린더가 세로로 길어지고 성겨 보인다 — 높이를 고정하고 폭만 늘어나게 한다. */
.dtpick{ border:1px solid var(--line); border-radius:16px; background:#fff;
  overflow:hidden; box-shadow:0 1px 3px rgba(38,45,56,.04); }
.dt-display{ padding:12px 15px; border-bottom:1px solid var(--line);
  background:linear-gradient(180deg, var(--cobalt-soft), #fff);
  font-size:14.5px; color:var(--ink); }
.dt-display b{ font-weight:800; }
.dt-display .dt-dow{ color:var(--cobalt-deep); font-weight:700; }
.dt-panel{ padding:11px 12px 13px; }

/* 년·월 고르는 줄 — 캘린더보다 존재감이 크지 않게 낮춘다 */
.dt-cal-head{ display:flex; align-items:center; gap:6px; padding:0 0 9px; }
.dt-selects{ display:flex; gap:5px; flex:1; justify-content:center; }
.dt-selects select{ border:1px solid var(--line); border-radius:8px; padding:6px 8px; font:inherit;
  font-size:13.5px; font-weight:700; color:var(--ink); background:#fff; cursor:pointer; }
.dt-year{ min-width:78px; } .dt-month{ min-width:58px; }
.dt-nav{ width:30px; height:30px; flex:none; border:1px solid var(--line); border-radius:8px; background:#fff;
  color:var(--cobalt-deep); font-size:16px; line-height:1; cursor:pointer; transition:.15s; }
.dt-nav:hover{ border-color:var(--cobalt); background:var(--cobalt-soft); }

.dt-week{ display:grid; grid-template-columns:repeat(7,minmax(0,1fr)); margin-bottom:2px; }
.dt-week span{ text-align:center; font-size:11px; font-weight:700; color:var(--soft); padding:3px 0; }
.dt-week .sun{ color:var(--danger); } .dt-week .sat{ color:var(--cobalt-deep); }

.dt-days{ display:grid; grid-template-columns:repeat(7,minmax(0,1fr)); gap:1px; }
/* 정사각 대신 높이 고정 — 폭이 넓어져도 칸이 커지지 않는다 */
.dt-day{ height:38px; border:none; background:none; border-radius:9px; font:inherit; font-size:13.5px;
  color:var(--ink); cursor:pointer; transition:.12s;
  display:flex; align-items:center; justify-content:center; }
.dt-day.empty{ visibility:hidden; cursor:default; }
.dt-day.sun{ color:var(--danger); } .dt-day.sat{ color:var(--cobalt-deep); }
.dt-day:hover:not(.empty):not(.on){ background:var(--cobalt-soft); }
/* 선택 — 파스텔 톤 안에서 도드라지되 형광은 아니게 */
.dt-day.on{ background:var(--cobalt-deep); color:#fff; font-weight:800;
  box-shadow:0 2px 8px rgba(76,147,214,.32); }
.dt-day.on.sun, .dt-day.on.sat{ color:#fff; }

.dt-time{ margin-top:12px; padding-top:11px; border-top:1px solid var(--line); }
.dt-time-lab{ display:block; font-size:12.5px; font-weight:700; color:var(--ink); margin-bottom:8px; }
.dt-time-ctrl{ display:flex; align-items:center; flex-wrap:nowrap; gap:6px; }
.dt-ampm{ display:inline-flex; flex:none; border:1px solid var(--line); border-radius:8px; overflow:hidden; }
.dt-ampm button{ border:none; background:#fff; color:var(--soft); font:inherit; font-size:12.5px;
  font-weight:700; padding:7px 11px; cursor:pointer; white-space:nowrap; transition:.15s; }
.dt-ampm button.on{ background:var(--cobalt-deep); color:#fff; }
.dt-hour,.dt-min{ flex:1 1 0; min-width:0; border:1px solid var(--line); border-radius:8px; padding:7px 8px;
  font:inherit; font-size:13.5px; background:#fff; color:var(--ink); }
.dt-colon{ font-size:12.5px; color:var(--soft); }

/* ═══════════════ 드래그 정렬(앨범·섹션) ═══════════════ */
.drag-hint{ font-size:12.5px; }
.thumb .drag-badge{ position:absolute; top:6px; left:6px; z-index:2; color:#fff; font-size:13px;
  line-height:1; text-shadow:0 1px 3px rgba(0,0,0,.5); cursor:grab; opacity:.85; }
.gallery-grid.sortable .thumb{ cursor:grab; }
.gallery-grid.sortable .thumb.dragging{ opacity:.4; }
.thumb.dragging{ transform:scale(.97); }
.save-hint{ font-size:12.5px; margin-top:8px; min-height:1em; }
.save-hint.saving{ color:var(--faint); } .save-hint.done{ color:var(--ok); } .save-hint.err{ color:var(--danger); }
.sortlist{ display:flex; flex-direction:column; gap:8px; }
.sortrow{ display:flex; align-items:center; gap:10px; padding:13px 14px; border:1.5px solid var(--line);
  border-radius:12px; background:#fcfdff; cursor:grab; transition:.12s; }
/* ⚠ display:flex 는 UA 의 [hidden]{display:none} 을 이긴다 — 이 규칙이 없어서 섹션을 꺼도
   순서 목록에서 사라지지 않았다(2026-09-01). .order-swap 과 같은 함정이다. */
.sortrow[hidden]{ display:none; }
.sortrow:hover{ border-color:var(--cobalt); background:var(--cobalt-soft); }
.sortrow.dragging{ opacity:.4; }
.sortrow .drag-badge{ color:var(--faint); font-size:16px; line-height:1; }
.sortrow__label{ font-weight:700; color:var(--ink); font-size:14.5px; }
.sortrow__label small{ font-weight:400; color:var(--soft); font-size:12px; margin-left:15px; }
/* 고정 섹션(인사말·혼주) — 목록에는 보이지만 끌 수 없다. 끌 수 없다는 걸 손잡이·커서로 알린다. */
.sortrow--fixed{ cursor:default; background:#f7f9fc; border-style:dashed; }
.sortrow--fixed:hover{ border-color:var(--line); background:#f7f9fc; }
.sortrow--fixed .drag-badge{ cursor:default; opacity:.55; font-size:13px; }
.sortrow--fixed .sortrow__label{ color:var(--soft); }

/* ═══════════════ 방명록 관리(운영자 모달) ═══════════════ */
.gb-admin{ margin-top:16px; padding-top:16px; border-top:1px dashed var(--line); }
.gb-admin > summary{ cursor:pointer; font-size:13px; font-weight:700; color:var(--cobalt-deep); list-style:none; }
.gb-admin > summary::-webkit-details-marker{ display:none; }
.gb-admin > summary::before{ content:'▸'; margin-right:6px; font-size:11px; color:var(--faint); }
.gb-admin[open] > summary::before{ content:'▾'; }
.gb-admin > summary .hint{ font-weight:400; color:var(--faint); font-size:12px; margin-left:4px; }
.gb-admin-list{ margin-top:12px; display:flex; flex-direction:column; gap:8px; }
.gb-admin-empty{ font-size:13px; color:var(--faint); padding:8px 0; }
.gb-admin-item{ position:relative; padding:11px 13px; border:1px solid var(--line); border-radius:11px;
  background:#fcfdff; transition:opacity .2s; }
.gb-admin-meta{ display:flex; align-items:baseline; gap:8px; margin-bottom:4px; }
.gb-admin-meta b{ font-size:13px; color:var(--ink); }
.gb-admin-meta span{ font-size:11px; color:var(--faint); }
.gb-admin-msg{ font-size:13px; color:var(--soft); line-height:1.6; white-space:pre-line; padding-right:52px; }
.gb-admin-del{ position:absolute; top:10px; right:10px; border:1px solid #efdad9; background:#fff;
  color:var(--danger); border-radius:8px; padding:5px 10px; font:inherit; font-size:12px; font-weight:600; cursor:pointer; }
.gb-admin-del:hover{ background:#fdf5f5; }
.gb-admin-del:disabled{ opacity:.5; cursor:default; }

/* ═══════════════ 표시설정: 미니라벨 / 선택 버튼 / 폰트 카드 ═══════════════ */
.mini-label{ font-size:13px; font-weight:700; color:var(--ink); margin-bottom:9px; }
.mini-label .hint{ font-weight:400; color:var(--faint); font-size:12px; margin-left:4px; }
.picker-open{ width:100%; display:flex; align-items:center; justify-content:space-between;
  padding:13px 15px; border:1.5px solid var(--line); border-radius:12px; background:#fcfdff;
  font:inherit; cursor:pointer; margin-bottom:12px; transition:.15s; }
.picker-open:hover{ border-color:var(--cobalt); background:var(--cobalt-soft); }
.picker-open__val{ font-weight:700; color:var(--ink); font-size:14.5px; }
.picker-open__act{ color:var(--cobalt-deep); font-size:13px; font-weight:600; }

/* 앨범 유형 모달 내 선택 카드 */
.gt-pick{ border:none; background:none; padding:0; cursor:pointer; }
.gt-pick.sel .gt-card{ border-color:var(--cobalt); background:var(--cobalt-soft); }
.gt-pick.sel .gt-name{ color:var(--cobalt-deep); }

/* 한글 폰트 선택 카드 */
.kfont-row{ display:grid; grid-template-columns:repeat(3,1fr); gap:9px; }
.kfont{ cursor:pointer; position:relative; }
.kfont input{ position:absolute; width:0; height:0; opacity:0; margin:0; }
.kf-card{ display:block; border:1.5px solid var(--line); border-radius:12px; padding:14px 6px 10px;
  text-align:center; background:#fcfdff; transition:.15s; }
.kfont input:checked + .kf-card{ border-color:var(--cobalt); background:var(--cobalt-soft); }
.kf-sample{ display:block; font-size:17px; color:var(--ink); line-height:1.2; margin-bottom:8px; min-height:22px;
  white-space:nowrap; }
.kfs-batang{ font-family:'Gowun Batang', serif; }
.kfs-sans{ font-family:'Pretendard', sans-serif; }
.kfs-buri{ font-family:'ChosunGu', sans-serif; }
.kf-name{ display:block; font-size:11.5px; font-weight:700; color:var(--soft); }
.kfont input:checked + .kf-card .kf-name{ color:var(--cobalt-deep); }

/* 예식 종료 잠금 배너 */
.lock-banner{ display:flex; gap:12px; align-items:flex-start; padding:15px 17px; margin:0 4px 18px;
  background:#fff7f6; border:1px solid #f2d9d7; border-radius:13px; }
.lock-ico{ font-size:18px; line-height:1.3; }
.lock-banner b{ display:block; color:#c8615d; font-size:14px; margin-bottom:3px; }
.lock-banner span{ font-size:12.5px; color:var(--soft); line-height:1.6; }

/* ═══════════════ 전체 저장 고정 바 ═══════════════ */
.savebar{ position:fixed; left:0; right:0; bottom:0; z-index:30;
  background:rgba(255,255,255,.93); backdrop-filter:blur(10px); border-top:1px solid var(--line);
  padding:12px 16px; padding-bottom:calc(12px + env(safe-area-inset-bottom)); box-shadow:0 -4px 20px rgba(120,170,225,.10); }
.savebar__inner{ max-width:760px; margin:0 auto; display:flex; align-items:center; justify-content:space-between; gap:14px; }
.savebar__hint{ font-size:12.5px; color:var(--soft); line-height:1.4; }
.savebar #saveAllBtn{ flex:none; min-width:150px; }
body:has(.savebar){ padding-bottom:82px; }
/* 전체 저장 진행바 (사진 업로드 중 렉처럼 보이지 않도록) */
.savebar__progress{ position:absolute; left:0; right:0; top:0; height:3px; background:rgba(76,147,214,.14);
  opacity:0; transition:opacity .2s ease; pointer-events:none; }
.savebar__progress.on{ opacity:1; }
.savebar__bar{ display:block; height:100%; width:0; background:var(--cobalt-deep); border-radius:0 3px 3px 0;
  transition:width .28s cubic-bezier(.4,.1,.2,1); }
@media (max-width:520px){ .savebar__hint{ display:none; } .savebar #saveAllBtn{ width:100%; } .savebar__inner{ display:block; } }

/* 비밀번호 변경 링크(하단 소형 버튼) */
.pw-link-row{ text-align:left; margin:4px 2px 0; }
.pw-link{ background:none; border:none; padding:0; cursor:pointer; font-family:inherit;
  font-size:13px; font-weight:600; color:var(--soft); text-decoration:underline; text-underline-offset:3px; }
.pw-link:hover{ color:var(--cobalt-deep); }

/* ── QR 코드 모달 ── */
.qr-warn{ display:flex; gap:10px; align-items:flex-start;
  background:#fff6f2; border:1px solid #f6d9cd; border-radius:12px;
  padding:12px 14px; margin-bottom:14px; font-size:13px; line-height:1.65; color:#7a4a3a; }
.qr-warn b{ flex:none; font-weight:800; color:#c2492c; }
.qr-box{ display:flex; flex-direction:column; align-items:center; gap:10px;
  padding:18px; background:#fff; border:1px solid var(--line); border-radius:14px; }
/* 하트는 세로가 짧아 정사각과 크기가 다르다 — 높이를 맞춰 두면 모양을 바꿔도 모달이 덜컹이지 않는다. */
/* ⚠ 240px 고정이면 팝업(max-height:88vh) 안에서 옵션·안내까지 합쳐 넘쳐 세로 스크롤이 생겼다
   (2026-09-02 지적). 화면 높이에 맞춰 줄여 팝업이 한 화면에 들어오게 한다. */
.qr-box img{ width:auto; height:min(176px, 26vh); max-width:100%; display:block; image-rendering:pixelated; }
/* ⚠ display 를 준 요소는 UA 의 [hidden]{display:none} 을 이긴다 — 이 두 줄이 없으면
   로딩과 그림이 **동시에** 자리를 차지해 팝업이 그만큼 길어진다(2026-09-02 실측). */
.qr-box img[hidden]{ display:none; }
.qr-loading[hidden]{ display:none; }
/* 서버가 그리는 1초 동안 자리를 지킨다 — 빈 칸만 있으면 고장 난 줄 안다 */
.qr-loading{ height:min(176px, 26vh); display:flex; flex-direction:column; align-items:center;
  justify-content:center; gap:10px; font-size:12.5px; color:var(--soft); }
.qr-loading i{ width:22px; height:22px; border-radius:50%; display:block;
  border:2px solid var(--line); border-top-color:var(--cobalt-deep); animation:qrSpin .8s linear infinite; }
@keyframes qrSpin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){ .qr-loading i{ animation:none; } }
/* 곡선이 있는 하트에 픽셀 확대를 쓰면 가장자리가 계단진다. */
.qr-box img.is-heart{ image-rendering:auto; }
.qr-url{ font-size:12px; color:var(--soft); word-break:break-all; text-align:center; }
.qr-tip{ margin-top:10px; font-size:12px; color:var(--faint); text-align:center; }

/* ── QR 잠금 화면 — 아직 만들기 전 ──────────────────────────────────────────
   ⚠ 진짜 QR 그림 요청(GET /customer/qr.png)이 곧 **발급 기록**이라, 만들기 전에는 절대
     부르면 안 된다. 그래서 여기 보이는 것은 서버를 부르지 않는 **가짜 QR(장식용 SVG)** 이고
     블러를 씌워 "아직 잠겨 있다"를 눈으로 알린다.
   ⚠ 높이를 .qr-box img 와 같은 값으로 맞춘다 — 만들기 전후로 팝업이 덜컹이지 않게. */
.qr-lock{ position:relative; width:min(176px, 26vh); height:min(176px, 26vh); }
.qr-lock[hidden]{ display:none; }
/* ⚠ 176px 안에 29칸이라 한 칸이 6px 남짓이다 — blur 4px 를 주면 격자가 통째로 뭉개져
     "빈 회색 판"으로 보였다(2026-09-03 확인). 흐리되 QR 인 것은 알아볼 만큼만 남긴다. */
.qr-lock__fake{ width:100%; height:100%; display:block;
  filter:blur(2.2px); opacity:.55; }
/* 버튼이 앉는 자리 — 옅은 막을 한 겹 더 깔아 가짜 QR 이 글자를 방해하지 않게 한다 */
.qr-lock__veil{ position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:9px;
  background:rgba(255,255,255,.62); border-radius:10px; }
.qr-lock__veil .btn{ min-height:40px; padding:0 20px; }
.qr-lock__hint{ font-size:11.5px; line-height:1.5; color:var(--soft); text-align:center; }
@media (prefers-reduced-motion:reduce){ .qr-lock__fake{ filter:blur(1.6px); } }

/* 아직 만들기 전의 [이미지 저장] — 누를 것이 없다는 걸 보이게만 하고 클릭은 JS 가 막는다 */
.btn.is-off{ opacity:.42; pointer-events:none; }

/* ── QR 모양·색 고르기 ── */
.qr-opt{ display:flex; align-items:center; gap:12px; margin-top:14px; }
.qr-opt__label{ flex:none; width:34px; font-size:13px; font-weight:700; color:var(--soft); }
.qr-shapes{ display:flex; gap:8px; }
.qr-shape{ display:inline-flex; align-items:center; gap:6px; cursor:pointer;
  padding:8px 14px; border:1px solid var(--line); border-radius:999px;
  background:#fff; font-family:inherit; font-size:13px; font-weight:600; color:var(--soft); }
.qr-shape:hover{ border-color:var(--cobalt-deep); color:var(--cobalt-deep); }
.qr-shape.is-on{ border-color:var(--cobalt-deep); background:var(--cobalt-deep); color:#fff; }
.qr-shape__ico{ font-size:14px; line-height:1; }
.qr-shape__ico--heart{ color:#c2492c; }
.qr-shape.is-on .qr-shape__ico--heart{ color:#fff; }

.qr-colors{ display:flex; flex-wrap:wrap; gap:10px; align-items:center; }
/* 고른 색의 HEX — 견본을 없앤 뒤 "지금 무슨 색인지"를 알려 주는 유일한 단서다 */
.qr-colors__hint{ font-family:var(--mono); font-size:12px; color:var(--soft); letter-spacing:.02em; }
/* 색 자체가 버튼이라, 고른 표시는 테두리가 아니라 바깥 링으로 준다(색을 가리지 않는다). */
.qr-sw{ position:relative; width:26px; height:26px; padding:0; cursor:pointer;
  border:1px solid rgba(0,0,0,.12); border-radius:50%; background:var(--sw,#000); }
.qr-sw.is-on{ box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--cobalt-deep); }
/* 직접 고르기 — 색상판을 여는 input 은 스와치 뒤에 숨기고 겉면만 보인다. */
.qr-sw--pick{ display:inline-block; overflow:hidden;
  background:
    linear-gradient(#fff,#fff) padding-box,
    conic-gradient(#e24b3b,#e2a03b,#d8d84a,#4fb463,#4c93d6,#8a5ad6,#e24b3b) border-box;
  border:3px solid transparent; }
.qr-sw--pick::after{ content:''; position:absolute; inset:0; border-radius:50%;
  background:var(--sw,#2E2A24); }
.qr-sw--pick input{ position:absolute; inset:0; width:100%; height:100%;
  opacity:0; border:none; padding:0; cursor:pointer; }
.qr-note{ margin-top:10px; font-size:12px; line-height:1.6; color:var(--soft);
  background:var(--cobalt-soft); border-radius:10px; padding:9px 12px; }
.qr-note b{ font-weight:700; color:var(--cobalt-deep); }
/* 실제로 밝은 색을 골랐을 때만 뜨는 경고 — 상시 안내와 색으로 구분한다 */
.qr-note--warn{ background:#fdf3ee; color:#8a5236; }
.qr-note--warn b{ color:#c2492c; }
/* 주소가 잠겼을 때의 안내 — 오류가 아니라 상태 설명이라 붉은색을 쓰지 않는다 */
.slug-msg.locked{ color:#7a4a3a; }

/* 전체 저장 로딩 오버레이 — 전체화면 원형 진행 */
.save-overlay{ position:fixed; inset:0; z-index:200; display:none; flex-direction:column; align-items:center; justify-content:center; gap:16px;
  background:rgba(247,251,254,.55); backdrop-filter:blur(1.2px); -webkit-backdrop-filter:blur(1.2px); }
.save-overlay.on{ display:flex; }
.save-ring{ position:relative; width:84px; height:84px; }
.save-ring svg{ width:84px; height:84px; transform:rotate(-90deg); }
.save-ring__bg{ fill:none; stroke:rgba(76,147,214,.18); stroke-width:7; }
.save-ring__fg{ fill:none; stroke:var(--cobalt-deep); stroke-width:7; stroke-linecap:round;
  stroke-dasharray:214; stroke-dashoffset:214; transition:stroke-dashoffset .25s ease; }
.save-ring__pct{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; font-size:15px; font-weight:800; color:var(--cobalt-deep); }
.save-overlay__label{ font-size:14px; font-weight:600; color:var(--ink); }

/* 템플릿 샘플 보기 링크 */
.tpl-preview{ float:right; font-size:12px; font-weight:600; color:var(--cobalt-deep); text-decoration:none;
  padding:4px 7px; border:1px solid var(--line); border-radius:8px; margin-bottom: 10px; }
.tpl-preview:hover{ border-color:var(--cobalt); background:var(--cobalt-soft); }

/* 앨범·약도 삭제 버튼(폼 없이 단독) — 삭제 예정 표시용 */
.thumb-x.gal-del, .thumb-x.map-del{ position:absolute; top:5px; right:5px; z-index:3; cursor:pointer; }

/* 고른 사진을 올리기 전에 하나씩 빼는 ✕. 선택이 누적되므로(2026-09-02) 빼는 수단이 함께 있어야 한다. */
.pv-wrap .pv-x{ position:absolute; top:-4px; right:-4px; z-index:3; width:18px; height:18px; padding:0;
  border:1px solid var(--line); border-radius:50%; background:rgba(255,255,255,.96); color:var(--soft);
  font-size:10px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; }
.pv-wrap .pv-x:hover{ background:rgba(192,69,69,.95); border-color:rgba(192,69,69,.95); color:#fff; }

/* 소멸 안내 / 정보 배너(고객 대시보드) */
.info-note{ display:flex; gap:12px; align-items:flex-start; padding:14px 16px; margin:0 4px 18px;
  background:var(--cobalt-soft); border:1px solid #d4e7f8; border-radius:13px; }
.info-note__ico{ font-size:17px; line-height:1.4; }
.info-note div{ font-size:12.5px; color:var(--soft); line-height:1.6; }
.info-note b{ color:var(--cobalt-deep); font-weight:700; }

/* ═══════════════════════════════════════════════════════════════
   3a — 라이트 글래스 디자인 시스템 (design_handoff_invitation_form)
   핸드오프 확정값을 그대로 사용. 고객 대시보드 · 고객 홈 · 운영자 콘솔이
   같은 토큰/표면을 공유한다. (이전 블루 글래스 레이어 대체 — 백업: dashboard.css.pre3a)
   ═══════════════════════════════════════════════════════════════ */
:root{
  /* 배경 */
  --g-bg:#eef1f5;
  --g-mesh-1:#dfe7f0; --g-mesh-2:#e7e2ee; --g-mesh-3:#e3ebe6;
  /* 텍스트 4단계 */
  --ink:#262d38;
  --soft:rgba(38,45,56,.6);
  --faint:rgba(38,45,56,.45);
  --ghost:rgba(38,45,56,.3);
  /* 악센트 — iOS 시스템 블루. 채도를 살리고, 면은 반투명 틴트로 깔아 유리 위에 얹힌 느낌을 낸다 */
  --acc:#007aff; --acc-ink:#0063d1;
  --acc-bg:rgba(0,122,255,.12);
  --acc-line:rgba(0,122,255,.32);
  --acc-glow:0 0 0 3px rgba(0,122,255,.16);
  /* 글래스 표면 (알파가 낮을수록 배경이 더 비침) */
  --gl-head:rgba(255,255,255,.56);
  --gl-card:rgba(255,255,255,.5);
  --gl-note:rgba(255,255,255,.46);
  --gl-field:rgba(255,255,255,.7);
  --gl-solid:rgba(255,255,255,.75);
  --gl-line:rgba(255,255,255,.9);
  --gl-blur:blur(30px) saturate(185%);
  /* 구분선 */
  --line:rgba(38,45,56,.1);
  --line-soft:rgba(38,45,56,.08);
  /* 반경 */
  --r-pill:999px; --r-preview:28px; --r-head:24px; --r-card:22px;
  --r-share:18px; --r-act:16px; --r-field:14px;
  --radius:var(--r-card);
  /* 그림자 */
  --sh-head:0 8px 26px rgba(38,45,56,.08);
  --sh-card:0 2px 12px rgba(38,45,56,.05);
  --sh-preview:0 10px 30px rgba(38,45,56,.1);
  --shadow:var(--sh-head);
  /* 타이포 */
  --sans:'Pretendard','Apple SD Gothic Neo',system-ui,-apple-system,sans-serif;
  --serif:'Gowun Batang',serif;
  --mono:ui-monospace,Menlo,'SF Mono',monospace;
  /* 전환 */
  --ease-ios:cubic-bezier(.32,.72,0,1);
}

/* ── 배경: 베이스 + 3중 radial mesh. 이 레이어가 있어야 glass 의 blur 가 의미를 갖는다 ── */
html{ min-height:100%; }
body{
  min-height:100vh; background:var(--g-bg); color:var(--ink);
  font-family:var(--sans); -webkit-font-smoothing:antialiased;
}
body::before{
  content:''; position:fixed; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(120% 70% at 12% 0%,   var(--g-mesh-1) 0%, transparent 60%),
    radial-gradient(100% 60% at 100% 8%,  var(--g-mesh-2) 0%, transparent 55%),
    radial-gradient(90% 60% at 50% 100%,  var(--g-mesh-3) 0%, transparent 60%);
}

/* backdrop-filter 미지원 브라우저: 불투명 fallback */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :root{
    --gl-head:rgba(255,255,255,.85); --gl-card:rgba(255,255,255,.85);
    --gl-note:rgba(255,255,255,.85); --gl-field:rgba(255,255,255,.92);
    --gl-solid:rgba(255,255,255,.92);
  }
}

/* ── 공통 표면: 기존 컴포넌트를 3a 글래스로 매핑 ── */
.topbar{
  background:rgba(238,241,245,.55);
  -webkit-backdrop-filter:var(--gl-blur); backdrop-filter:var(--gl-blur);
  border-bottom:.5px solid var(--line-soft);
  /* 로고가 커진 만큼 세로 패딩을 줄여 상단바 높이 증가를 최소화 */
  padding:10px 20px;
}
.pagehead h1{ color:var(--ink); font-weight:600; letter-spacing:-.035em; }
.pagehead p{ color:var(--faint); letter-spacing:-.01em; }

.card{
  background:var(--gl-card);
  -webkit-backdrop-filter:var(--gl-blur); backdrop-filter:var(--gl-blur);
  border:.5px solid rgba(255,255,255,.88);
  border-radius:var(--r-card); box-shadow:var(--sh-card);
}
.card > h2{ font-weight:600; font-size:15px; letter-spacing:-.03em; color:var(--ink); }
.card > .desc{ color:var(--faint); font-size:12px; line-height:1.65; letter-spacing:-.01em; }

.savebar{
  background:linear-gradient(180deg, rgba(238,241,245,0), rgba(238,241,245,.85) 45%);
  -webkit-backdrop-filter:var(--gl-blur); backdrop-filter:var(--gl-blur);
  border-top:none; box-shadow:none;
}

/* 입력 요소 */
.field input, .field select, .field textarea, .parent-group input,
.search-box input, .slug-input, .dtpick, .picker-open, .inline-form select,
.transit-add__row select, .dt-selects select{
  background:var(--gl-field); border:.5px solid rgba(38,45,56,.14);
  border-radius:var(--r-field); color:var(--ink);
  font-size:14.5px; letter-spacing:-.01em;
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
}
.field textarea{ line-height:1.7; resize:none; }
.field input:focus, .field select:focus, .field textarea:focus, .parent-group input:focus,
.search-box input:focus, .slug-input:focus-within{
  outline:none; border-color:var(--acc);
  box-shadow:var(--acc-glow); background:rgba(255,255,255,.82);
}

/* 버튼 */
.btn{ border-radius:var(--r-pill); font-weight:500; letter-spacing:-.01em; }
/* ── Liquid Glass 버튼 ──────────────────────────────────────────────
   유리는 "반투명한 흰 면"이 아니다. 세 가지가 동시에 있어야 유리로 읽힌다:
     ① 거의 투명한 틴트   — 면을 채우지 않고 뒤를 그대로 통과시킨다(알파 .12 수준)
     ② 굴절              — backdrop blur 에 채도/밝기를 함께 올려 뒤가 번지며 맑아진다
     ③ 스펙큘러 림       — 가장자리에서 빛이 꺾이는 밝은 테. 균일한 border 가 아니라
                           한쪽이 밝고 반대쪽이 사라지는 그라데이션 테여야 한다.
   ③ 은 border 로는 못 만들어서 ::before + mask 로 1px 그라데이션 테를 두른다. */
/* Powder Glass — 파우더 블루 틴트 + 무채색 스펙큘러 림 + 상단 하이라이트 스트릭.
   ::before 마스크 기법은 그대로 두고 색 값만 교체했다(2026-08-28). */
.btn-primary{
  position:relative;
  background:linear-gradient(135deg, rgba(186,227,255,.34), rgba(255,255,255,.16) 55%, rgba(186,227,255,.28));
  color:var(--acc-ink); font-weight:600; border:none;
  -webkit-backdrop-filter:blur(18px) saturate(180%);
  backdrop-filter:blur(18px) saturate(180%);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,.6),      /* 윗면에 고인 빛 */
    inset 0 -1px 1px rgba(255,255,255,.22),    /* 아랫면 반사 */
    0 10px 24px rgba(140,190,255,.2);          /* 떠 있는 그림자 — 블루 톤 */
}
/* 스펙큘러 림 — 무채색. 좌상단이 밝고 가운데가 가라앉았다가 우하단에서 다시 살아난다 */
.btn-primary::before{
  content:''; position:absolute; inset:0; border-radius:inherit; padding:1.5px; pointer-events:none;
  background:linear-gradient(135deg,
    rgba(255,255,255,.9), rgba(200,208,220,.75) 50%, rgba(255,255,255,.85) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite:exclude;
}
/* 윗면을 스치는 좁은 흰 하이라이트 */
.btn-primary::after{
  content:''; position:absolute; left:8%; right:32%; top:8%; height:34%;
  border-radius:999px; background:rgba(255,255,255,.75); filter:blur(4px);
  opacity:.8; pointer-events:none;
}
.btn-primary:hover{
  background:linear-gradient(135deg, rgba(186,227,255,.42), rgba(255,255,255,.18) 55%, rgba(186,227,255,.36));
  box-shadow:0 14px 30px rgba(140,190,255,.26), inset 0 1px 0 rgba(255,255,255,.55);
}
.btn-primary:active{
  background:linear-gradient(135deg, rgba(140,190,255,.46), rgba(255,255,255,.16) 55%, rgba(140,190,255,.40));
  box-shadow:0 6px 16px rgba(140,190,255,.22), inset 0 1px 0 rgba(255,255,255,.5);
}
.btn-primary[disabled]{
  background:rgba(140,190,255,.14); color:var(--ghost); box-shadow:none; cursor:default;
}
.btn-primary[disabled]::before{ opacity:.35; }
.btn-primary[disabled]::after{ opacity:.25; }
/* backdrop-filter 미지원 브라우저 — 유리가 안 되면 최소한 읽히게 면을 조금 채운다 */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .btn-primary{ background:linear-gradient(135deg, rgba(186,227,255,.62), rgba(255,255,255,.5) 55%, rgba(186,227,255,.56)); }
}
.btn-ghost, .btn-danger{
  background:var(--gl-solid); border:.5px solid rgba(38,45,56,.1); color:var(--ink);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
}
.btn-danger{ color:#b4534f; }

/* 리스트 · 정렬 · 접기 · 방명록 표면 */
.item, .transit-row, .gb-admin-item{
  background:var(--gl-note); border:.5px solid rgba(255,255,255,.88);
  border-radius:var(--r-act);
}
.item.clickable:hover{ background:rgba(255,255,255,.68); border-color:var(--acc-line); }
.sortrow{ background:var(--gl-note); border:.5px solid rgba(255,255,255,.88); border-radius:var(--r-act); }
.sortrow:hover{ background:var(--acc-bg); border-color:var(--acc-line); }
.foldable, .fold-details{ background:rgba(255,255,255,.4); border:.5px solid rgba(255,255,255,.88); border-radius:var(--r-share); }
.opt-block .choice .opt, .choice .opt, .gt-card, .kf-card, .picker-open{
  background:rgba(255,255,255,.44); border:.5px solid rgba(255,255,255,.88); border-radius:var(--r-field);
}
.choice input:checked + .opt, .gtype input:checked + .gt-card, .kfont input:checked + .kf-card,
.gt-pick.sel .gt-card{ background:var(--acc-bg); border-color:var(--acc); color:var(--acc-ink); }

/* 배지 · 필 */
.card > h2 .badge, .stage-tag, .transit-row__type, .pill-off{
  background:rgba(255,255,255,.5); color:var(--faint);
  border:.5px solid rgba(255,255,255,.6); font-weight:500;
}
.pill-on{ background:var(--acc-bg); color:var(--acc-ink); border:.5px solid rgba(255,255,255,.6); }

/* 배너 · 플래시 */
.info-note{
  background:rgba(255,255,255,.46); border:.5px solid rgba(255,255,255,.9);
  border-radius:var(--r-act); box-shadow:var(--sh-card);
  -webkit-backdrop-filter:var(--gl-blur); backdrop-filter:var(--gl-blur);
}
.info-note div{ color:var(--faint); }
.info-note b{ color:var(--soft); font-weight:600; }
.lock-banner{ background:rgba(190,110,105,.14); border:.5px solid rgba(255,255,255,.7); border-radius:var(--r-act); }
.flash-ok{ background:var(--acc-bg); border:.5px solid rgba(255,255,255,.7); color:var(--acc-ink); }
.flash-err{ background:rgba(190,110,105,.16); border:.5px solid rgba(255,255,255,.7); color:#b4534f; }

/* 모달 */
.modal__backdrop{ background:rgba(38,45,56,.26); -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px); }
/* 반투명 흰색(.78) + 블러라 어두운 백드롭이 비쳐 회색으로 탁해 보였다 → 불투명 흰 지면으로. */
.modal__box{
  background:#fff;
  border:.5px solid rgba(38,45,56,.10); border-radius:var(--r-preview);
  box-shadow:0 20px 60px rgba(38,45,56,.20);
}
.modal__head, .modal__foot{ background:transparent; border-color:var(--line-soft); }
.modal__x{ background:rgba(255,255,255,.6); border:.5px solid rgba(255,255,255,.8); }

/* 예식일시 선택기 · 썸네일 톤 맞춤 */
.dt-display{ border-color:rgba(255,255,255,.7); }
.dtpick, .picker-open{ border-radius:var(--r-act); }
.thumb{ border-radius:var(--r-field); border-color:rgba(255,255,255,.7); }

/* ═══════════════ 3a 입력 폼 (아코디언 위저드) ═══════════════ */
/* 폭은 상단 "자동 소멸" 안내(.info-note)와 동일하게 — .wrap 콘텐츠 폭에서 좌우 4px 인셋 */
.wiz{ max-width:none; margin:0 4px; padding:0; }
/*.wiz-scroll{ padding:14px 0 16px; }*/


/* B. 섹션 카드(아코디언) */
.wiz-sec{
  margin-bottom:9px; border-radius:var(--r-card); background:var(--gl-card);
  -webkit-backdrop-filter:var(--gl-blur); backdrop-filter:var(--gl-blur);
  border:.5px solid rgba(255,255,255,.88); box-shadow:var(--sh-card); overflow:hidden;
}
.wiz-sec__head{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:16px 17px; cursor:pointer; width:100%; background:none; border:none;
  font-family:inherit; text-align:left; -webkit-tap-highlight-color:transparent;
}
.wiz-sec__head:focus-visible{ outline:2px solid var(--acc); outline-offset:-2px; border-radius:var(--r-card); }
.wiz-sec__left{ display:flex; align-items:center; gap:12px; min-width:0; }
.wiz-sec__no{ font-family:var(--mono); font-weight:400; font-size:10.5px; color:var(--ghost); }
.wiz-sec__label{ font-weight:500; font-size:14.5px; color:var(--ink); letter-spacing:-.03em; }
.wiz-sec__right{ display:flex; align-items:center; gap:9px; }
.wiz-chip{
  padding:5px 11px; border-radius:var(--r-pill); font-weight:500; font-size:10.5px;
  letter-spacing:-.01em; border:.5px solid rgba(255,255,255,.6); white-space:nowrap;
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  background:rgba(255,255,255,.5); color:rgba(38,45,56,.42);
  transition:background .15s linear, color .15s linear;
}
.wiz-chip.on{ background:var(--acc-bg); color:var(--acc-ink); }

/* 섹션 헤더의 "사용" 토글 — 청첩장에 이 항목을 넣을지 여부. 펼치기와는 별개다. */

/* ── 신랑·신부 표시 순서 토글 ──
   섹션 헤더의 "사용" 토글(.wiz-use)과 달리 본문 안에 놓이는 줄이라,
   스위치를 왼쪽에 두고 설명을 오른쪽에 편다. 설명이 길어 두 줄이 될 수 있어 위쪽 정렬. */



/* ── 항상 펼쳐 두는 설정 카드(공개·주소·QR) ──
   아코디언과 같은 카드 껍데기를 쓰되 머리를 눌러 접지 않는다 — 편집을 시작할 때
   가장 먼저 보는 값이라 접어 둘 이유가 없다(2026-08-31 지시). */
.cfg-card{
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-card);
  box-shadow:var(--sh-card); overflow:hidden; margin-bottom:12px;
}
.cfg-card__head{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:15px 18px 13px; border-bottom:1px solid var(--line);
}
.cfg-card__label{ font-size:14px; font-weight:700; color:var(--ink); letter-spacing:-.01em; }
.cfg-card__body{ padding:4px 18px 6px; }

/* 카드 안의 세 줄은 같은 열에서 시작해야 한다.
   ⚠ .item 은 제 테두리와 16px 패딩을 갖고 있어, 카드 안에 그대로 두면 글자가 안쪽으로 밀려
     주소 라벨과 열이 어긋난다(2026-08-31 지적). 카드 안에서는 테두리를 걷고 여백을 0 으로 맞춘다. */
.cfg-card__body > .item{
  border:0; background:none; border-radius:0;
  padding:14px 0; gap:14px;
}
.cfg-card__body > .item + .item,
.cfg-card__body > .cfg-row + .item,
.cfg-card__body > .item + .cfg-row{ border-top:1px solid var(--line-soft, var(--line)); }
/* 주소 줄 — 라벨·입력·안내가 한 덩어리 */
.cfg-row{ display:flex; flex-direction:column; gap:7px; padding:14px 0; }
.cfg-row .wiz-f__label{ margin:0; }
/* ── 혼주 "고인" 체크박스 ──
   토글이 아니라 체크박스다(2026-08-31 지시) — 켜고 끄는 설정이 아니라 사실 표시라서,
   네모 체크가 의미에 맞고 네 자리에 나란히 놓아도 시끄럽지 않다. */
.late-chk{
  display:inline-flex; align-items:center; gap:5px;
  margin-top:6px; cursor:pointer; user-select:none;
}
.late-chk input{
  width:15px; height:15px; margin:0; flex:none;
  accent-color:var(--cobalt); cursor:pointer;
}
.late-chk span{ font-size:12px; color:var(--soft); letter-spacing:-.01em; }
.late-chk input:checked + span{ color:var(--ink); font-weight:600; }
/* ⚠ display:flex 는 UA 의 [hidden]{display:none} 을 이긴다 — 흑백 표지가 아닌 템플릿에서
   "표지 사진 흑백" 줄을 감추려면 [hidden] 규칙을 따로 둬야 한다(2026-08-31). */
.order-swap[hidden]{ display:none; }
.order-swap{
  display:flex; align-items:flex-start; gap:10px; cursor:pointer;
  padding:11px 13px; margin:0 0 2px;
  border:1px solid var(--line); border-radius:12px; background:var(--gl-field);
}
.order-swap .switch{ flex:none; margin-top:1px; }
.order-swap__t{
  display:flex; flex-direction:column; gap:3px;
  font-size:13px; font-weight:600; color:var(--ink); line-height:1.4;
}
.order-swap__t .hint{
  font-size:11.5px; font-weight:400; color:var(--soft); letter-spacing:-.01em;
}
.wiz-use{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  padding:2px 0 2px 4px; /* 손가락으로 누르기 좋게 */
}
.wiz-use__txt{
  font-weight:500; font-size:10.5px; letter-spacing:-.01em;
  color:rgba(38,45,56,.3); transition:color .15s linear;
}
.wiz-sec:not(.off) .wiz-use__txt{ color:var(--soft); }
/* 헤더용 축소 스위치 */
.switch--sm{ width:44px; height:27px; }
.switch--sm .slider::before{ width:23px; height:23px; left:2px; top:2px; }
.switch--sm input:checked + .slider::before{ transform:translateX(17px); }

/* 펼침 기호 — 열림 상태만 나타낸다 */
.wiz-sec__sign{
  font-weight:300; font-size:15px; color:rgba(38,45,56,.28);
  width:10px; text-align:center; line-height:1;
}
.wiz-sec__sign::before{ content:'＋'; }
.wiz-sec.open .wiz-sec__sign::before{ content:'−'; }

/* 사용 안 함 — 내용은 그대로 두고 헤더만 조용하게(접기·편집은 계속 가능) */
.wiz-sec.off{ background:rgba(255,255,255,.34); }
.wiz-sec.off .wiz-sec__label{ color:rgba(38,45,56,.42); }
.wiz-sec.off .wiz-sec__no{ color:rgba(38,45,56,.2); }

/* 아코디언 열림 전환 — iOS 감각 */
.wiz-sec__body{
  display:grid; grid-template-rows:0fr;
  transition:grid-template-rows .22s var(--ease-ios);
}
.wiz-sec.open .wiz-sec__body{ grid-template-rows:1fr; }
.wiz-sec__inner{ overflow:hidden; }
.wiz-sec__pad{ padding:0 17px 18px; display:flex; flex-direction:column; gap:14px; }
.wiz-hint{
  border-top:.5px solid var(--line); padding-top:14px;
  font-weight:400; font-size:12px; line-height:1.65; color:rgba(38,45,56,.5); letter-spacing:-.01em;
}
.wiz-f__label{ font-weight:500; font-size:11px; color:var(--faint); letter-spacing:.01em; margin-bottom:7px; }
.wiz-sec__pad input[type=text], .wiz-sec__pad input[type=tel],
.wiz-sec__pad input[type=url], .wiz-sec__pad textarea{
  width:100%; box-sizing:border-box; padding:13px 14px;
  border:.5px solid rgba(38,45,56,.14); border-radius:var(--r-field);
  background:var(--gl-field); font-family:inherit; font-size:14.5px;
  color:var(--ink); letter-spacing:-.01em;
}
.wiz-sec__pad textarea{ line-height:1.7; resize:none; }
.wiz-sec__pad input:focus, .wiz-sec__pad textarea:focus{
  outline:none; border-color:var(--acc); box-shadow:var(--acc-glow);
}
/* 2열 배치(이름/연락처 등) */
.wiz-pair{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
@media (max-width:359px){ .wiz-pair{ grid-template-columns:1fr; } }

/* 사진 그리드 */
.wiz-photos{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px; }
.wiz-photo{ aspect-ratio:1; border-radius:var(--r-field); overflow:hidden; position:relative;
  background:linear-gradient(160deg,#dfe6ee,#cfd8e3); }
.wiz-photo img{ width:100%; height:100%; object-fit:cover; display:block; }
.wiz-photo--add{
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  border:.5px dashed rgba(38,45,56,.25); background:rgba(255,255,255,.4);
  font-weight:300; font-size:22px; color:rgba(38,45,56,.35);
}
.wiz-photo--add:hover{ background:rgba(255,255,255,.6); border-color:var(--acc); color:var(--acc); }


/* iOS 확대 방지: 입력 폰트 16px 미만이면 포커스 시 줌 — 터치 기기에서만 16px */
@media (hover:none) and (pointer:coarse){
  .wiz-sec__pad input, .wiz-sec__pad textarea,
  .field input, .field select, .field textarea{ font-size:16px; }
}

/* 성능: 뷰포트 밖 섹션 카드의 blur 비용을 줄인다 */
.wiz-sec{ content-visibility:auto; contain-intrinsic-size:auto 64px; }

@media (prefers-reduced-motion:reduce){
  .wiz-sec__body, .switch .slider, .switch .slider::before{ transition:none; }
}

/* 설정 그룹 구분 라벨 */
/* 설정 / 입력 항목 그룹 구분 라벨.
   --mono(시스템 모노)를 쓰던 자리라 이 화면에서 혼자 튀었다 → 본문과 같은 서체로. */
.wiz-group-label{
  display:flex; align-items:center; gap:10px;
  font-family:var(--sans); font-size:12px; font-weight:700; letter-spacing:.02em;
  color:var(--soft);
  margin:34px 0 12px; padding-left:2px;
}
.wiz-group-label::after{                     /* 라벨 오른쪽으로 흐르는 헤어라인 */
  content:""; flex:1; height:1px; background:var(--line);
}
.wiz-group-label:first-of-type{ margin-top:6px; }   /* 맨 위 그룹은 위 여백을 줄인다 */
/* 설정 섹션 — 콘텐츠 섹션보다 한 단계 조용하게 */
.wiz-sec--cfg{ background:rgba(255,255,255,.42); }
.wiz-sec--cfg .wiz-sec__no{ font-size:12px; color:rgba(38,45,56,.22); }

/* 섹션 본문 안의 select */
.wiz-sec__pad select{
  width:100%; box-sizing:border-box; padding:13px 14px;
  border:.5px solid rgba(38,45,56,.14); border-radius:var(--r-field);
  background:var(--gl-field); font-family:inherit; font-size:14.5px;
  color:var(--ink); letter-spacing:-.01em;
}
.wiz-sec__pad select:focus{
  outline:none; border-color:var(--acc); box-shadow:var(--acc-glow);
}
/* ⚠ 바로 위 `width:100%` 가 `.transit-add__row select{width:120px}`(224행) 을 덮는다 —
   명시도가 같고 파일에서 더 뒤라서 이긴다. 그러면 셀렉트가 줄 전체를 먹고 옆의 "추가" 버튼이
   행 밖으로 밀려나 **화면에서 사라진다**(2026-09-02 실측: select w=724px, button right=1318 > row right=1260).
   교통 줄만 다시 좁혀 둔다. 좁은 화면 규칙(228행)도 같은 이유로 여기서 한 번 더 적는다. */
.wiz-sec__pad .transit-add__row select{ flex:none; width:120px; }
@media (max-width:420px){
  .wiz-sec__pad .transit-add__row select{ flex:1 1 auto; width:auto; min-width:0; }
}
/* 섹션 안에 들어간 기존 .field 위젯은 여백을 폼 gap 에 맡긴다 */
.wiz-sec__pad .field{ margin:0; }
.wiz-sec__pad .switch-row{ border-bottom:none; padding:2px 0; }
.wiz-f__label .hint{ font-weight:400; color:var(--ghost); margin-left:4px; }


/* ═══════════════ PC 2단 — 미리보기 + 편집 (1024px↑ 전용) ═══════════════
   ★ 시작점 미만은 픽셀 하나도 바뀌면 안 된다. 아래 기본 규칙 2개는 "새로 추가한 요소를
     숨기는" 것뿐이고, 레이아웃을 바꾸는 규칙은 전부 아래 min-width 블록 안에 있다.
     ⚠ 시작점을 1200px → 1024px 로 낮췄다(2026-09-01 지시).
       그 전에는 1024~1199px(노트북·태블릿 가로)에서 폼이 760px 에 묶인 채 좌우가 텅 비고
       미리보기도 없었다 — 넓은데 아무것도 안 쓰는 구간이었다.
       1024~1279px 은 기기 칸을 300px 로 좁혀 편집 폭을 확보한다(맨 아래 블록).
     기존 규칙은 수정하지 않았다. */
/* ⚠ 반드시 `.wrap--split > .pv` 로 좁힌다. 그냥 `.pv` 로 두면 **업로드 썸네일**
   (.preview-strip .pv / .pv-wrap .pv)까지 display:none 이 걸린다 — 같은 클래스 이름을 쓴다.
   그래서 사진을 고르면 64px 빈 칸에 `대표` 버튼만 남아 있었다(2026-09-01 발견). */
.wrap--split > .pv{ display:none; }   /* 모바일: 미리보기 패널 없음 — 기존 화면 그대로 */
.savebar__url{ display:none; }

@media (min-width:1024px){
  .wrap--split{
    max-width:1300px;
    display:grid; grid-template-columns:minmax(0,356px) minmax(0,1fr);
    column-gap:48px;
    row-gap:0;
  }
  /* 좌측은 세로로 쌓인 바+기기 — 이 배치는 그대로 둔다 */
  .wrap--split > .pv{ display:flex; flex-direction:column; gap:12px; }
  /* ══ 2단 레이아웃 — 좌측 미리보기는 "고정", 우측만 스크롤 ══
     ⚠ 예전에는 좌측에 position:sticky 를 걸었다. sticky 는 고정이 아니라
       "자기 grid area 안에서만 따라붙는" 규칙이라, 스크롤을 내리면 area 를 벗어나며
       위로 밀려 올라갔다 — 실측 405px 이 움직였다(2026-08-31).
       → 페이지(body)를 아예 스크롤하지 않게 하고, 우측 .split__main 한 곳만 스크롤한다.
         그러면 좌측은 문서가 움직이지 않으니 흔들릴 여지 자체가 없다.

     세로 구성은 상단바 / (좌 미리보기 | 우 편집) / 푸터 세 층이다.
     푸터는 붙박이가 아니다 — 우측 칸 안쪽 맨 끝에 있어 스크롤을 다 내려야 보인다. */
  /* ⚠ 이 세 줄은 반드시 body.split-page 로 좁힌다.
     예전에는 그냥 body 였는데, dashboard.css 는 편집 화면만 쓰는 게 아니라
     대시보드(/customer)·관리자(/admin)도 함께 쓴다 — 넓은 화면에서 그 화면들까지
     overflow:hidden 이 걸려 **스크롤이 통째로 죽어 있었다**(2026-09-01 발견).
     편집 화면만 "페이지는 안 움직이고 오른쪽 칸만 스크롤"하는 구조다.
     범위는 :has() 로 잡는다 — 이 파일이 이미 body:has(.savebar) 를 쓰고 있고,
     JSP 에 클래스를 새로 다는 방식은 서버를 재시작해야 해서 그 전까지 편집 화면이 깨진다. */
  html{ height:100%; }
  body:has(.wrap--split){ height:100%; overflow:hidden; display:flex; flex-direction:column; }
  body:has(.wrap--split) .topbar{ flex:none; }
  /* 가운데 층 — 남는 높이를 전부 먹는다. min-height:0 이 없으면 내용이 밀어내 넘친다. */
  .wrap--split{
    flex:1 1 auto; min-height:0;
    align-items:stretch;
    overflow:hidden;
    padding:26px 24px 0;
  }
  /* 좌측 — 스크롤도 없고 움직이지도 않는다 */
  .wrap--split > .pv{
    grid-column:1; grid-row:auto;
    position:static;
    height:100%; min-height:0;
    overflow:hidden;
  }
  /* 우측 — 스크롤은 여기서만 일어난다 */
  .split__main{
    grid-column:2; grid-row:auto;
    height:100%; min-height:0;
    overflow-y:auto; overflow-x:hidden;
    overscroll-behavior:contain;      /* 끝까지 내려도 뒤 페이지로 스크롤이 넘어가지 않는다 */
    padding-bottom:24px;
    /* 스크롤바는 패딩 박스 **바깥**(테두리 자리)에 그려진다 — 그래서 padding-right 를 주면
       막대는 그대로 두고 카드만 안으로 들어와 사이에 간격이 생긴다(2026-08-31 지적:
       "스크롤이 오른쪽에 딱 붙어 있다"). 카드 폭은 그만큼 줄어든다. */
    padding-right:18px;
  }
  /* 우측 안쪽 요소는 원래 폭 규칙을 그대로 쓴다 */
  .split__main > *{ max-width:760px; width:100%; margin-left:0; }
  .split__main > *:not(:last-child){ margin-bottom:32px; }
  /* 마지막 항목(비밀번호 변경)과 푸터 사이는 한 칸만 */
  .split__main > .pw-link-row{ margin-bottom:8px; }
  /* 푸터 — 우측 스크롤 칸 맨 끝. 세로로 쌓으면 91px 이나 먹어 답답해서 한 줄로 눕힌다. */
  .split__main > .site-foot{ max-width:none;
    display:flex; align-items:center; justify-content:center; gap:16px;
    padding:16px 20px 8px; margin-top:4px; border-top:1px solid var(--line); }
  .site-foot .insta{ padding:4px 11px; font-size:12px; gap:6px; }
  .site-foot .insta svg{ width:13px; height:13px; }
  .site-foot .copy{ margin-top:0; font-size:11.5px; }
  /* ── 우측 스크롤바 — iOS 유리 느낌 ──
     대시보드의 파스텔 톤에 맞춰, 막대는 살짝 비치는 유리 알갱이처럼 두고 트랙은 비운다.
     ⚠ 이 스크롤바는 창이 아니라 .split__main 안쪽 것이라 페이지 전체 스크롤바와 무관하다. */
  .split__main{ scrollbar-width:thin; scrollbar-color:rgba(126,158,201,.42) transparent; }
  .split__main::-webkit-scrollbar{ width:13px; }
  .split__main::-webkit-scrollbar-track{ background:transparent; }
  .split__main::-webkit-scrollbar-thumb{
    /* 안쪽으로 물러서게 해 막대가 벽에 붙지 않고 떠 있는 것처럼 보인다 */
    border:4px solid transparent; background-clip:padding-box;
    border-radius:999px;
    background-color:rgba(126,158,201,.38);
    box-shadow:inset 0 0 0 1px rgba(255,255,255,.55);
    transition:background-color .18s ease; }
  .split__main::-webkit-scrollbar-thumb:hover{ background-color:rgba(112,146,193,.62); }
  .split__main::-webkit-scrollbar-thumb:active{ background-color:rgba(96,132,182,.78); }
  .pv__bar{ display:flex; align-items:center; gap:8px; padding:0 4px; }
  .pv__tag{ font-family:var(--mono); font-size:10.5px; color:var(--ghost); letter-spacing:.04em; }
  .pv__spacer{ flex:1; }
  /* ★ 한쪽은 <button>, 다른 쪽은 <a> 라 상속되는 line-height 가 달라(버튼 normal / 링크 1.6)
       패딩이 같은데도 높이가 1~2px 어긋나 보였다. 높이를 직접 고정해 둘을 맞춘다. */
  .pv__btn{ display:inline-flex; align-items:center; justify-content:center; gap:5px;
    height:30px; padding:0 11px; line-height:1;
    border-radius:var(--r-pill); border:1px solid var(--line); background:var(--gl-field);
    font-family:inherit; font-size:12px; font-weight:600; color:var(--soft);
    cursor:pointer; text-decoration:none; white-space:nowrap; }
  .pv__btn:hover{ border-color:var(--acc-line); color:var(--acc-ink); }

  /* ⚠ transform:scale() 로 줄이지 않는다 — 터치·스크롤 좌표가 깨진다. 폭 자체로 조절한다.
     ★ 크기는 vh 를 계산하지 않고 **남는 높이에서 브라우저가 직접 역산**하게 둔다.
       예전에는 (100vh - 상수) 로 폭을 구했는데, 상단바·푸터·저장바 높이를 상수에 일일이
       더해야 해서 레이아웃을 한 번 고칠 때마다 어긋났다(푸터를 넣자 154px 이 넘쳐 잘렸다).
       flex 로 남는 높이를 받고 aspect-ratio 로 폭을 얻으면 그 상수가 통째로 사라진다.
       422 x 894 = 화면 402x874 + 좌우/상하 프레임 패딩 10px 씩. */
  /* ⚠ flex:1 1 auto + height:auto 면 폰이 남는 세로를 **채우려고 늘어나** aspect-ratio 를
     무시한다 — 화면(.pv__screen)은 402/894 로 멈추고 검은 프레임만 길어져 아래가 잘린다
     (2026-09-01 1400×1100 에서 확인). 세로를 기준으로 잡고 줄어들게만 둔다. */
  .pv__phone{ flex:0 1 auto; min-height:0;
    aspect-ratio:422 / 894; height:100%; width:auto; max-width:100%; margin:16px auto 18px;
    padding:10px; background:#22262e; border-radius:54px;
    box-shadow:0 8px 26px rgba(38,45,56,.10), inset 0 0 0 1px rgba(255,255,255,.08); }
  /* iPhone 17 Pro 논리 해상도 402×874. 화면 배경은 기기 색과 같게 둔다 —
     흰색이면 축소 배율의 실낱 오차가 밝은 틈으로 드러난다. */
  .pv__screen{ position:relative; width:100%; aspect-ratio:402 / 874;
    border-radius:44px; overflow:hidden; background:#22262e; }
  /* ★ 청첩장을 프레임 폭 그대로 렌더하면 300px 안팎에서 그려져 실제 기기보다 좁아진다.
       그래서 iframe 은 402×874 로 렌더하고 프레임에 맞춰 축소한다.
       --pv-k 는 스크립트가 ceil(프레임 폭/402) 로 계산해 넣는다(내림하면 오른쪽에 흰 틈).
       핸드오프 문서는 scale 을 금지했지만("좌표가 깨진다"), transform-origin 을 0 0 으로 두면
       최신 브라우저는 포인터·스크롤 좌표를 알아서 매핑한다 — 미리보기 축소의 표준 기법이다. */
  /* ⚠ 모서리를 iframe 자신에게도 준다 — 배율이 어긋난 순간에도 네모난 모서리가 프레임 위로
     드러나지 않게. scale(k) 로 줄어드니 반지름은 k 로 나눠 넣는다(화면 반지름 44px 과 일치). */
  /* ⚠ 모서리는 자르는 대신 덮는다 — 모바일 카드와 같은 처방(2026-09-03). 축소된 iframe 의
     내용은 둥근 overflow 로도, iframe 자신의 border-radius 로도 잘리지 않는다.
     바깥 그림자(퍼짐 12px = 폰 패딩 10px 보다 크게)로 둥근 윤곽 바깥의 네모 자투리를 지운다. */
  .pv__screen::after{ content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
    transform:translateZ(0);
    border-radius:44px; box-shadow:0 0 0 12px #22262e; }
  .pv__screen iframe{ position:absolute; top:0; left:0;
    width:402px; height:874px; border:0; display:block;
    border-radius:calc(44px / var(--pv-k, 1));
    transform:scale(var(--pv-k, 1)); transform-origin:0 0; }

  /* ── 미리보기 로딩 ──
     기기 화면(#22262e) 그대로면 검은 판이라 칙칙하고 고장난 것처럼 보인다(2026-08-31 지적).
     청첩장이 놓일 자리를 흐릿한 종이 틀로 깔고 그 위에 진행바를 얹어, 무엇을 기다리는지 보이게 한다.
     ⚠ display:flex 가 UA 의 [hidden]{display:none} 을 이기므로 [hidden] 규칙을 함께 둔다. */
  .pv__loading{ position:absolute; inset:0; z-index:2;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:26px;
    padding:32px 26px;
    background:linear-gradient(170deg, #f7f9fc 0%, #eef3f9 55%, #e9eff7 100%);
    opacity:1; transition:opacity .32s ease; }
  .pv__loading[hidden]{ display:none; }
  .pv__loading.is-done{ opacity:0; pointer-events:none; }

  /* 종이 틀 — 사진 한 장과 글줄 몇 개. 실제 청첩장의 첫 화면 짜임을 흉내낸다 */
  .pv__skel{ width:100%; display:flex; flex-direction:column; align-items:center; gap:11px; }
  .pv__skel-img, .pv__skel-line{
    background:linear-gradient(100deg, rgba(190,206,226,.30) 30%, rgba(214,228,244,.62) 50%, rgba(190,206,226,.30) 70%);
    background-size:220% 100%; border-radius:8px;
    animation:pvShimmer 1.5s ease-in-out infinite; }
  .pv__skel-img{ width:78%; aspect-ratio:3/4; border-radius:14px; margin-bottom:6px; }
  .pv__skel-line{ height:11px; width:64%; }
  .pv__skel-line--lg{ height:15px; width:46%; }
  .pv__skel-line--sm{ width:34%; }
  @keyframes pvShimmer{ 0%{ background-position:120% 0 } 100%{ background-position:-20% 0 } }

  /* 진행바 — 끝을 알 수 없는 기다림이라 좌우로 훑는 막대 하나로 둔다 */
  .pv__bar-wrap{ width:100%; display:flex; flex-direction:column; align-items:center; gap:9px; }
  .pv__prog{ width:60%; height:3px; border-radius:999px; overflow:hidden;
    background:rgba(124,188,235,.22); }
  .pv__prog span{ display:block; width:38%; height:100%; border-radius:999px;
    background:linear-gradient(90deg, var(--cobalt), var(--cobalt-deep));
    animation:pvSlide 1.15s cubic-bezier(.65,.05,.36,1) infinite; }
  @keyframes pvSlide{ 0%{ transform:translateX(-105%) } 100%{ transform:translateX(275%) } }
  .pv__loading-t{ font-size:11.5px; letter-spacing:.02em; color:var(--soft); }

  /* 움직임을 줄여 달라는 설정이면 흐르는 연출 대신 은은한 명멸만 남긴다 */
  @media (prefers-reduced-motion:reduce){
    .pv__skel-img, .pv__skel-line{ animation:pvPulse 1.6s ease-in-out infinite; }
    .pv__prog span{ animation:none; width:100%; opacity:.5; }
    @keyframes pvPulse{ 0%,100%{ opacity:.5 } 50%{ opacity:.9 } }
  }
  /* ★ 예식 일시 선택기 — 편집 컬럼이 760px 까지 넓어지면 .dt-day 가 aspect-ratio:1 이라
       날짜 한 칸이 100px 가까이 커져 오히려 읽기 나빠졌다. 폭을 묶어 한 칸을 52px 선에 둔다.
       (시간 입력 줄도 같은 컨테이너 안이라 함께 정리된다) */
  /* 편집 컬럼이 760px 까지 넓어져도 캘린더는 이 폭 안에서만 자란다.
     날짜 칸 높이를 고정해 두었으므로 폭이 늘어도 세로로 길어지지 않는다. */
  .dtpick{ max-width:470px; }
  /* 앨범 썸네일 — 폭이 넓어져도 한 장이 커지지 않게 칸 수를 늘린다(최소 96px) */
  .gallery-grid{ grid-template-columns:repeat(auto-fill, minmax(96px, 1fr)); gap:9px; }
  .preview-strip .pv{ width:56px; height:56px; }

  /* 넓은 화면에서는 하단 붙박이 저장바를 쓰지 않는다 — 화면 아래를 가로로 가로막아
     미리보기 기기가 애매하게 잘렸다. 저장 버튼만 우하단 플로팅으로 띄운다.
     (모바일은 기존 붙박이 저장바 그대로 — 이 블록은 1024px 이상에서만 적용된다) */
  .savebar{ left:auto; right:30px; bottom:26px; width:auto;
    padding:0; background:none; border-top:none; box-shadow:none;
    -webkit-backdrop-filter:none; backdrop-filter:none; }
  /* ⚠ 붙박이 바를 비켜 주려고 body 아래에 둔 82px 을 여기서 되돌린다.
     플로팅에서는 비켜 줄 바가 없는데도 그 여백이 남아, 화면 맨 아래에 빈 띠가 깔리고
     그만큼 미리보기 기기가 잘렸다 — "저장바가 푸터처럼 보인다"의 정체다. */
  body:has(.savebar){ padding-bottom:0; }
  .savebar__inner{ max-width:none; margin:0; padding:0; display:block; }
  /* 공개 주소·안내 문구는 플로팅에서 뺀다. 주소는 상단 "공개 설정 · 주소" 섹션에서 볼 수 있다. */
  .savebar__url, .savebar__hint{ display:none; }
  .savebar #saveAllBtn{
    padding:14px 28px; border-radius:var(--r-pill);
    box-shadow:0 14px 34px rgba(38,45,56,.28); }
}

/* ═══ 1024~1279px — 노트북 가로. 기기 칸을 좁혀 편집 폭을 확보한다 ═══
   356px 그대로 두면 편집 컬럼이 570px 아래로 내려가 폼 두 칸(.wiz-pair)이 답답해진다. */
@media (min-width:1024px) and (max-width:1279px){
  .wrap--split{
    grid-template-columns:minmax(0,300px) minmax(0,1fr);
    column-gap:32px;
    padding:20px 18px 0;
  }
}

/* ═══ 대시보드(카드 목록) — PC 에서 2단 ═══
   편집 화면만 2단(.wrap--split)이라 대시보드·관리자는 넓은 화면에서도 760px 한 줄에 묶여
   "모바일 페이지를 크게 띄운 것"처럼 보였다(2026-09-01 지적).
   카드 높이가 제각각이므로 align-items:start 로 늘어나지 않게 두고, 머리말만 두 칸을 차지한다. */
@media (min-width:1024px){
  .wrap--cards{
    max-width:1120px;
    display:grid; grid-template-columns:repeat(2, minmax(0,1fr));
    column-gap:22px; align-items:start;
  }
  .wrap--cards > .pagehead{ grid-column:1 / -1; }
  /* 잠금 안내는 한 줄로 걸쳐 둔다 — 반쪽에 들어가면 문장이 잘게 접힌다 */
  .wrap--cards > .lock-banner{ grid-column:1 / -1; }
  /* 빈 상태 카드도 한 줄 — 옆이 비어 허전하다 */
  .wrap--cards > .card:only-of-type{ grid-column:1 / -1; }
}
@media (min-width:1440px){
  .wrap--cards{ max-width:1240px; column-gap:26px; }
}

/* ═══ QR 팝업 — 세로가 짧은 화면에서 한 화면에 담기게 조인다 ═══
   내용을 빼지 않고 여백만 줄인다. 그래도 아주 짧은 화면(뷰포트 600 미만)에서는 스크롤이 남는데,
   그때는 스크롤이 나는 편이 글자를 더 줄이는 것보다 낫다. */
@media (max-height:820px){
  #qrModal .modal__box{ max-height:92vh; }
  #qrModal .modal__head{ padding:16px 22px 12px; }
  #qrModal .modal__body{ padding:14px 22px; }
  #qrModal .qr-box{ padding:12px; gap:8px; }
  #qrModal .qr-opt{ margin-top:10px; }
  #qrModal .qr-note{ margin-top:8px; padding:8px 12px; }
  #qrModal .qr-tip{ margin-top:6px; }
  #qrModal .actions{ margin-top:12px; }
  #qrModal .qr-box img,
  #qrModal .qr-loading{ height:min(176px, 22vh); }
}

/* ═══════════════ 모바일 미리보기(플로팅 버튼 → 플로팅 카드) ═══════════════
   PC(1024px↑)는 좌측 2단 패널(.pv)이 늘 떠 있으므로 이 UI 는 보이지 않아야 한다.

   ⚠ **PC 패널과 같은 방식이다 — 402×874 로 그린 뒤 통째로 축소한다**(2026-09-03 지시로 통일).
     그 전에는 "보고 있는 기기의 폭"을 기준으로 그렸는데, 카드가 화면보다 좁다 보니 지면이
     가로로 눌려 **봉투(002)·아치(003)처럼 비율로 그린 오프닝 도형이 깨졌다.** 402 고정이면
     조판이 실기기와 픽셀 단위로 같고, 화면에는 그것을 줄여서 보여 줄 뿐이다.
   ⚠ 배율은 JS(fitMobile)가 --mpv-k 로 넣는다. 없으면 1배(옛 동작)라 스크립트가 죽어도
     화면이 비지 않는다. 자세한 것은 아래 .mpv__phone 주석. */
.mpv-fab{ display:none; }
.mpv{ display:none; }

@media (max-width:1023.98px){
  /* ── 떠 있는 버튼: savebar(전체 저장) 위에 겹치지 않게 얹는다 ── */
  .mpv-fab{ position:fixed; right:14px; z-index:31;
    bottom:calc(80px + env(safe-area-inset-bottom));
    display:inline-flex; align-items:center; gap:9px;
    min-height:44px; padding:0 17px 0 14px;
    border:1px solid var(--acc-line); border-radius:999px;
    background:var(--gl-solid); color:var(--acc-ink);
    -webkit-backdrop-filter:var(--gl-blur); backdrop-filter:var(--gl-blur);
    font-family:inherit; font-size:13.5px; font-weight:700; letter-spacing:-.01em;
    box-shadow:0 8px 24px rgba(38,45,56,.14); cursor:pointer;
    transition:opacity .2s ease, transform .12s ease; }
  .mpv-fab:active{ transform:scale(.97); }
  /* 작은 폰 실루엣 — 외부 아이콘 의존 없이 테두리로만 그린다 */
  .mpv-fab__ico{ flex:none; width:13px; height:19px; border-radius:3px;
    border:1.6px solid currentColor; position:relative; }
  .mpv-fab__ico::after{ content:''; position:absolute; left:50%; bottom:1.5px;
    transform:translateX(-50%); width:5px; height:1.4px; border-radius:1px; background:currentColor; }
  /* 카드가 떠 있는 동안에는 버튼이 배경 위에 어정쩡하게 남지 않게 접는다 */
  body.mpv-open .mpv-fab{ opacity:0; pointer-events:none; }

  /* ── 카드 ── */
  /* ⚠ display:flex 를 주므로 [hidden] 짝이 반드시 있어야 한다 —
       브라우저 기본 [hidden]{display:none} 은 명시도에서 밀린다(2026-08·09 세 번 겪은 함정). */
  .mpv{ position:fixed; left:0; top:0; width:100%; height:100%; z-index:60;
    display:flex; align-items:flex-end; justify-content:center;
    /* 좌우 패딩이 곧 축소 배율이다 — 12px 이면 390px 폰에서 k=0.94, 8px 이면 0.96 이다.
       카드가 화면에서 뜬 느낌은 남기되 배율 손해는 줄인다. */
    padding:calc(20px + env(safe-area-inset-top)) 8px calc(10px + env(safe-area-inset-bottom)); }
  /* 주소창이 접히고 펴져도 카드가 잘리지 않게 — 지원하는 브라우저에서는 dvh 를 쓴다 */
  @supports (height:100dvh){ .mpv{ height:100dvh; } }
  .mpv[hidden]{ display:none; }
  .mpv__backdrop{ position:absolute; inset:0; background:rgba(22,38,60,.46);
    opacity:0; transition:opacity .24s ease; }
  .mpv.is-on .mpv__backdrop{ opacity:1; }
  .mpv__card{ position:relative; width:min(100%, 460px); height:100%;
    display:flex; flex-direction:column; overflow:hidden;
    background:#fff; border-radius:var(--r-card);
    box-shadow:0 18px 52px rgba(38,45,56,.28);
    transform:translateY(18px); opacity:0;
    transition:transform .26s cubic-bezier(.22,.68,.24,1), opacity .2s ease; }
  .mpv.is-on .mpv__card{ transform:translateY(0); opacity:1; }

  /* 손잡이 — 아래로 밀어 닫는 곳. 터치 영역을 44px 로 잡는다. */
  .mpv__grip{ flex:none; height:44px; display:flex; flex-direction:column;
    align-items:center; justify-content:center; gap:5px;
    border-bottom:1px solid var(--line); background:#fff;
    touch-action:none; cursor:grab; }
  .mpv__grip-bar{ width:38px; height:4px; border-radius:999px; background:rgba(38,45,56,.18); }
  .mpv__grip-t{ font-size:10.5px; color:var(--ghost); letter-spacing:-.01em; }

  /* ── 기기 목업 — PC 패널(.pv__phone)과 같은 방식 ─────────────────────────
     ⚠ **카드 폭 그대로 그리지 않는다**(2026-09-03 지시로 되돌림). 카드는 화면보다 좁아서
       그 폭으로 렌더하면 지면이 가로로 눌리고, **봉투(002)·아치(003)처럼 비율로 그린 도형이
       깨진다.** 402×874 로 그린 뒤 통째로 축소하면 조판이 실기기와 픽셀 단위로 같아진다.
     ⚠ 세로를 기준으로 잡고 줄어들게만 둔다 — 가로를 기준으로 하면 낮은 화면에서 프레임만
       길어져 아래가 잘린다(PC 에서 겪은 것과 같은 함정).
     ⚠ 배율(--mpv-k)은 JS(fitMobile)가 넣는다. 없으면 1배라 스크립트가 죽어도 화면이 비지 않는다. */
  /* ⚠ 위아래 여백을 준다(2026-09-03 지시 — "여백이 없어 정갈하지 못하다"). 목업이 손잡이·바에
     딱 붙어 있으면 팝업이 꽉 찬 느낌이라 답답하다. margin 은 flex 계산에 포함되므로 목업이
     그만큼 알아서 줄어든다 — 높이를 따로 빼 줄 필요가 없다. */
  .mpv__phone{ flex:0 1 auto; min-height:0;
    aspect-ratio:422 / 894; height:100%; width:auto; max-width:100%; margin:16px auto 18px;
    padding:8px; background:#22262e; border-radius:44px;
    box-shadow:0 8px 26px rgba(38,45,56,.16), inset 0 0 0 1px rgba(255,255,255,.08); }
  /* iPhone 17 Pro 논리 해상도 402×874. 화면 배경은 기기 색과 같게 둔다 —
     흰색이면 축소 배율의 실낱 오차가 밝은 틈으로 드러난다. */
  .mpv__screen{ position:relative; width:100%; aspect-ratio:402 / 874;
    border-radius:37px; overflow:hidden; background:#22262e; }
  /* ⚠ 모서리를 iframe 자신에게도 준다. 화면(.mpv__screen)의 둥근 overflow 가 이미 자르지만,
     배율이 한 프레임이라도 어긋나면(주소창 접힘 등) 지면의 **네모난 모서리**가 프레임 위로
     드러나 "마스크가 안 따진" 것처럼 보인다(2026-09-03). iframe 은 scale(k) 로 줄어드니
     반지름은 k 로 나눠 넣어야 화면 반지름(37px)과 같아진다. */
  /* ⚠ **둥근 모서리는 자르는 대신 덮는다**(2026-09-03).
     `.mpv__screen{border-radius+overflow:hidden}` 도, iframe 자신의 border-radius 도
     **축소(transform)된 iframe 의 내용에는 듣지 않는다** — 실제 편집 화면에서 003 처럼 지면이
     어두운 템플릿을 열면 네모난 모서리가 프레임 위로 드러났다("마스크가 안 따진다").
     mask-image · will-change · translateZ · contain:paint · isolation 다섯 가지를 실제 화면에서
     하나씩 넣어 봤지만 어느 것도 고치지 못했다 — 되풀이하지 말 것.
     → 대신 모서리 자투리를 **프레임 색으로 덮는다.** 바깥 그림자(번짐 0·퍼짐 10px)는 둥근
       테두리 **바깥쪽만** 칠하므로, 둥근 윤곽과 네모 모서리 사이의 자투리가 정확히 지워진다.
       퍼짐 10px 은 폰 패딩 8px 보다 크게 잡아 이음매가 남지 않게 한 값이다. */
  /* ⚠ `transform:translateZ(0)` 로 **덮개를 합성 레이어로 올린다.** 그냥 두면 축소된 iframe 이
     자기 레이어로 합성되면서 덮개보다 위에 그려져 아무것도 못 덮는다(z-index 만으로는 부족). */
  .mpv__screen::after{ content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
    transform:translateZ(0);
    border-radius:37px; box-shadow:0 0 0 10px #22262e; }
  .mpv__screen iframe{ position:absolute; top:0; left:0;
    width:402px; height:874px; border:0; display:block; background:#fff;
    border-radius:calc(37px / var(--mpv-k, 1));
    clip-path:inset(0 round calc(37px / var(--mpv-k, 1)));
    transform:scale(var(--mpv-k, 1)); transform-origin:0 0; }

  .mpv__loading{ position:absolute; inset:0; z-index:2;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:11px;
    background:#fff; transition:opacity .3s ease; }
  .mpv__loading[hidden]{ display:none; }
  .mpv__loading.is-done{ opacity:0; pointer-events:none; }
  .mpv__loading-t{ font-size:12px; color:var(--soft); letter-spacing:-.01em; }
  .mpv__spin{ width:22px; height:22px; border-radius:50%;
    border:2.5px solid rgba(38,45,56,.13); border-top-color:var(--acc-ink);
    animation:mpvSpin .8s linear infinite; }
  @keyframes mpvSpin{ to{ transform:rotate(360deg); } }
  @media (prefers-reduced-motion:reduce){
    .mpv__spin{ animation:none; }
    .mpv__card{ transition:none; }
  }

  .mpv__bar{ flex:none; display:flex; align-items:center; gap:8px;
    padding:9px 10px;
    border-top:1px solid var(--line); background:rgba(255,255,255,.96); }
  .mpv__note{ flex:1; min-width:0; font-size:11px; color:var(--soft);
    letter-spacing:-.01em; line-height:1.35; }
  .mpv__btn{ flex:none; min-height:40px; padding:0 14px;
    border:1px solid var(--line); border-radius:var(--r-field); background:#fff;
    font-family:inherit; font-size:12.5px; font-weight:700; color:var(--soft); cursor:pointer; }
  .mpv__btn:active{ background:rgba(255,255,255,.9); }
  .mpv__btn--x{ border-color:var(--acc-line); color:var(--acc-ink); }
  /* 아주 좁은 화면에서는 안내 문구를 접어 버튼 두 개가 찌부러지지 않게 한다 */
  @media (max-width:359px){ .mpv__note{ display:none; } }

  /* 카드가 떠 있는 동안 뒤 편집 화면이 함께 스크롤되지 않게 잠근다 */
  body.mpv-open{ overflow:hidden; }
}

/* ═══════════════ 운영자 콘솔 — 소멸 임박 · 비밀번호 초기화 (2026-09-02) ═══════════════ */
/* 소멸은 사진까지 되돌릴 수 없게 지우는 작업이라, 이 카드만 색으로 눈에 걸리게 둔다.
   ⚠ 이 톤은 운영자 화면 전용이다 — 청첩장 템플릿에는 소멸 안내를 넣지 않는다. */
.card--warn{ border-color:#f0dcc9; background:linear-gradient(180deg, #fffaf4, var(--card) 120px); }
.card--warn > h2{ color:#8a5a2b; }
.badge-warn{ background:#fbe9d6; color:#8a5a2b; }
.pill-warn{ background:#fbe9d6; color:#8a5a2b; }
.pill-danger{ background:#fbeaea; color:var(--danger); }

/* 값이 여럿인 상세 행 — 라벨 옆에 배지·안내가 나란히 온다.
   ⚠ .info-row .v 의 white-space:pre-line 을 끈다. 그대로 두면 마크업 개행이 빈 줄로 렌더돼
     행이 세로로 벌어진다(초대 문구 때문에 .v 자체의 pre-line 은 남겨 둬야 한다). */
.info-row .v-inline{ white-space:normal; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* 비밀번호 초기화 — 입력과 버튼을 한 줄로. 좁은 화면에서는 접힌다. */
.pw-reset{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.pw-reset input{ flex:1; min-width:0; padding:10px 12px; border:1px solid var(--line);
  border-radius:var(--r-field, 11px); background:var(--gl-field, #fff);
  font-family:inherit; font-size:13px; color:var(--ink); }
.pw-reset input:focus{ outline:none; border-color:var(--acc, #007aff); }
.ext-days{ flex:none; padding:9px 12px; border:1px solid var(--line);
  border-radius:var(--r-field, 11px); background:var(--gl-field, #fff);
  font-family:inherit; font-size:13px; color:var(--ink); }

/* ═══════════════ 운영자 콘솔 — 템플릿 판매가 (2026-09-05) ═══════════════ */
/* 여섯 줄뿐이라 표를 쓰지 않는다. 번호·이름·금액이 한 줄에 앉고, 금액칸만 오른쪽에 고정폭으로
   떨어져 세로로 가지런히 읽힌다(금액을 훑을 때 눈이 한 축만 따라가면 된다). */
.prices{ border:1px solid var(--line); border-radius:var(--r-field, 11px); overflow:hidden; }
.price-row{ display:flex; align-items:center; gap:12px; padding:11px 14px;
  border-bottom:1px solid var(--line); background:var(--card); }
.price-row:last-child{ border-bottom:none; }
.price-no{ flex:none; width:22px; font-family:'Cormorant Garamond', serif; font-size:13px;
  letter-spacing:.1em; color:var(--faint); }
.price-name{ flex:1; min-width:0; font-size:13.5px; font-weight:600; color:var(--ink);
  display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
/* 값이 비어 있는 줄에만 나온다. 첫 화면에 금액이 안 걸린다는 사실이 목록에서 바로 보여야 한다
   (코드에 기본가가 없으므로, 비어 있으면 정말로 "가격 문의"가 나간다). */
.price-ask{ font-style:normal; font-size:11px; font-weight:500; color:var(--faint);
  padding:2px 7px; border-radius:999px; background:var(--gl-field, #f4f6f9); }
.price-input{ flex:none; display:flex; align-items:center; gap:6px; }
.price-input input{ width:110px; padding:9px 11px; border:1px solid var(--line);
  border-radius:var(--r-field, 11px); background:var(--gl-field, #fff);
  font-family:inherit; font-size:13px; color:var(--ink); text-align:right; }
.price-input input:focus{ outline:none; border-color:var(--acc, #007aff); }
.price-input b{ flex:none; font-size:12.5px; font-weight:500; color:var(--soft); }

@media (max-width:420px){
  .price-row{ flex-wrap:wrap; gap:8px 10px; }
  .price-name{ flex:1 1 auto; }
  .price-input input{ width:96px; }
}

/* ═══════════════ 운영자 콘솔 — 대시보드 (2026-09-06) ═══════════════ */
/* 맨 위에서 "지금 어떤 상태인가"만 읽는 자리. 조회 전용이라 버튼을 두지 않는다. */
.kpis{ display:grid; grid-template-columns:repeat(auto-fit, minmax(min(100%,140px),1fr));
  gap:10px; margin-bottom:6px; }
.kpi{ padding:14px 16px; border:1px solid var(--line); border-radius:var(--r-field, 11px);
  background:var(--gl-field, #fff); }
.kpi__l{ font-size:11.5px; color:var(--faint); letter-spacing:-.01em; }
.kpi__n{ margin-top:5px; font-size:24px; font-weight:700; letter-spacing:-.03em; color:var(--ink);
  display:flex; align-items:baseline; gap:6px; }
/* 한 칸에 여러 숫자를 넣을 때(고객·청첩장·공개) 뒤쪽은 한 단계 낮춘다 */
.kpi__s{ font-size:14px; font-weight:600; color:var(--faint); letter-spacing:-.01em; }

.dash-sub{ margin:22px 0 12px; font-size:12.5px; font-weight:600; color:var(--soft);
  letter-spacing:-.01em; }

/* 막대 그래프 — 고객 대시보드(customer-home)의 방문 그래프와 같은 규격을 쓴다.
   ⚠ 값이 0 인 날도 칸을 남긴다. 빠지면 날짜 축이 어긋나 추세를 잘못 읽는다. */
.vgraph{ display:flex; align-items:flex-end; gap:4px; height:120px; }
.vbar-col{ flex:1 1 0; display:flex; flex-direction:column; align-items:center; height:100%; min-width:0; }
.vbar-track{ flex:1; width:100%; display:flex; align-items:flex-end; justify-content:center; }
.vbar{ width:70%; max-width:16px; min-height:3px; border-radius:3px 3px 2px 2px;
  background:var(--cobalt); }
.vbar.zero{ background:rgba(38,45,56,.1); }
.vbar-lab{ font-size:9.5px; color:var(--ghost, rgba(38,45,56,.35)); margin-top:6px; }

/* 샘플 열람 순위 — 숫자만 나열하면 비교가 안 돼서 1위 대비 막대를 함께 그린다. */
.rank{ list-style:none; margin:0; padding:0; }
.rank__i{ display:flex; align-items:center; gap:10px; padding:9px 0;
  border-bottom:1px solid var(--line); }
.rank__i:last-child{ border-bottom:none; }
.rank__no{ flex:none; width:20px; font-family:'Cormorant Garamond', serif; font-size:12.5px;
  letter-spacing:.1em; color:var(--faint); }
.rank__nm{ flex:none; width:104px; font-size:13px; font-weight:600; color:var(--ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rank__bar{ flex:1; min-width:0; height:6px; border-radius:999px;
  background:var(--gl-field, #f1f4f8); overflow:hidden; }
.rank__bar i{ display:block; height:100%; border-radius:999px; background:var(--cobalt);
  min-width:2px; }
.rank__c{ flex:none; min-width:34px; text-align:right; font-size:12.5px; font-weight:700;
  color:var(--soft); }

@media (max-width:520px){
  .kpi__n{ font-size:20px; }
  .rank__nm{ width:82px; font-size:12.5px; }
  .vgraph{ height:96px; }
}

/* 예식일 잠금(고객) — 예식일 당일부터는 날짜를 못 바꾼다.
   ⚠ 입력칸을 disabled 로 두지 않고 아예 다른 블록으로 바꾼다. 회색 입력칸은 "왜 안 눌리지"로
     읽히지만, 값 + 이유를 함께 보여 주면 묻지 않아도 알 수 있다. */
.wed-locked{ padding:14px 16px; border:1px solid var(--line); border-radius:var(--r-field, 11px);
  background:var(--gl-field, #f7f9fc); }
.wed-locked__d{ display:block; font-size:15px; font-weight:700; color:var(--ink);
  letter-spacing:-.02em; }
.wed-locked__m{ display:block; margin-top:6px; font-size:12px; line-height:1.5; color:var(--faint);
  word-break:keep-all; }

/* 대시보드 기간 선택 (2026-09-06) */
.range{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:16px; }
.range input[type="date"]{ padding:9px 11px; border:1px solid var(--line);
  border-radius:var(--r-field, 11px); background:var(--gl-field, #fff);
  font-family:inherit; font-size:13px; color:var(--ink); }
.range input[type="date"]:focus{ outline:none; border-color:var(--acc, #007aff); }
.range__t{ color:var(--faint); font-size:13px; }
/* 자주 쓰는 기간은 링크로 — 두 칸을 손으로 채우지 않아도 되게 한다 */
.range__p{ display:flex; align-items:center; gap:12px; margin-left:4px; }
.range__p a{ font-size:12px; color:var(--soft); text-decoration:none; border-bottom:1px solid var(--line); }
.range__p a:hover{ color:var(--ink); border-bottom-color:currentColor; }
/* KPI 라벨 옆 단위·기간 표시 */
.kpi__u{ font-weight:500; color:var(--ghost, rgba(38,45,56,.4)); }
/* 집계가 꺼진 환경(로컬·개발)에서 띄우는 안내 */
.stat-off{ display:inline-block; margin-top:6px; font-size:12px; font-weight:600; color:#8a5a2b; }
/* 기간이 길 때 — 막대 사이를 좁혀 60~90개도 한 화면에 들어오게 */
.vgraph--dense{ gap:1px; }
.vgraph--dense .vbar{ width:100%; max-width:none; border-radius:2px 2px 0 0; }

@media (max-width:520px){
  .range{ gap:6px; }
  .range input[type="date"]{ flex:1; min-width:0; padding:8px 9px; font-size:12.5px; }
  .range__p{ width:100%; margin-left:0; }
}

/* 소제목·라벨 옆 보조 문구는 한 칸 떨어뜨린다 — 붙으면 한 낱말처럼 읽힌다
   ("샘플을 많이 열어 본 순서같은 기간" / "기간 내 방문14일") */
.dash-sub .hint{ margin-left:7px; font-weight:400; }
.kpi__u{ margin-left:5px; }
