/* Preview UI — neutral operator console (Phase 1)
 *
 * Intentionally plain: white surface, hairline borders, soft drop shadow.
 * Distinct from any brand download skin (CMBG, etc.).
 *
 * 쓰는 법·규칙은 docs/preview-ui/DESIGN.md — 새 부품을 만들기 전에 읽고, 규칙을 바꾸면 같이 고친다.
 */

:root {
  --pv-bg: #f7f7f8;
  --pv-surface: #ffffff;
  --pv-border: #e6e6ea;
  --pv-text: #1a1a1f;
  --pv-text-soft: #6c6c75;
  --pv-text-mute: #9a9aa3;
  --pv-accent: #2563eb;
  --pv-accent-hover: #1d4ed8;
  --pv-danger: #dc2626;
  --pv-radius: 10px;
  --pv-radius-sm: 6px;
  --pv-shadow: 0 1px 2px rgba(20, 20, 30, 0.04), 0 2px 6px rgba(20, 20, 30, 0.04);
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

/* Pretendard 를 직접 싣는다.
   전에는 스택에 이름만 있고 **파일을 안 실었다.** 그래서 그 글꼴이 깔린 기기에서만
   Pretendard 로 보이고 나머지는 제각각이었다 — 게다가 순서가 4번째라 윈도우에서는
   Segoe UI 가 먼저 잡히고 한글은 맑은 고딕으로 떨어졌다. 화면마다 자모 모양과
   자간이 달라 보이던 것이 그 때문이다.

   가변 글꼴 하나로 굵기를 다 덮는다(400·500·600·700). 정적 파일을 굵기별로 받으면
   세 개에 2.3MB 인데 가변은 하나에 2MB 다. 운영 콘솔은 같은 사람이 반복해서 여는
   화면이라 첫 방문 뒤로는 캐시에서 나온다.

   swap 이라 글꼴이 늦게 와도 글자는 먼저 보인다 — 내려받는 동안 빈 화면이 되면
   그게 더 나쁘다. */
@font-face {
  font-family: 'Pretendard';
  src: url('/public/fonts/PretendardVariable.woff2') format('woff2-variations');
  font-weight: 45 920;
  font-style: normal;
  font-display: swap;
}

.preview-body {
  background: var(--pv-bg);
  color: var(--pv-text);
  font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, "Segoe UI",
    "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
  font-size: 14px;
  line-height: 1.45;
  min-height: 100vh;
}

/* ---------- Login ---------- */

.preview-body--login {
  display: flex;
  align-items: center;
  justify-content: center;
}

.preview-login-wrap {
  width: 100%;
  display: flex;
  justify-content: center;
  padding: 40px 16px;
}

.preview-login-card {
  width: 100%;
  max-width: 360px;
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  padding: 32px 28px;
  box-shadow: var(--pv-shadow);
}

.preview-login-title {
  margin: 0 0 4px;
  font-size: 20px;
  font-weight: 600;
}

.preview-login-subtitle {
  margin: 0 0 24px;
  color: var(--pv-text-soft);
  font-size: 13px;
}

.preview-login-error {
  margin: 0 0 16px;
  padding: 10px 12px;
  background: #fff1f2;
  color: var(--pv-danger);
  border: 1px solid #fecdd3;
  border-radius: var(--pv-radius-sm);
  font-size: 13px;
}

.preview-field {
  display: block;
  margin-bottom: 14px;
}

.preview-field-label {
  display: block;
  margin-bottom: 6px;
  color: var(--pv-text-soft);
  font-size: 12px;
  font-weight: 500;
}

.preview-field input {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  font-size: 14px;
  background: var(--pv-surface);
  color: var(--pv-text);
  outline: none;
  transition: border-color 0.15s;
}

.preview-field input:focus {
  border-color: var(--pv-accent);
}

/* ---------- Buttons ---------- */

.preview-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--pv-border);
  background: var(--pv-surface);
  color: var(--pv-text);
  border-radius: var(--pv-radius-sm);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.preview-btn:hover { background: #fafafb; }
.preview-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.preview-btn--primary {
  background: var(--pv-accent);
  border-color: var(--pv-accent);
  color: #fff;
  width: 100%;
  padding: 10px 14px;
}

.preview-btn--primary:hover { background: var(--pv-accent-hover); border-color: var(--pv-accent-hover); }

.preview-btn--ghost {
  background: transparent;
}

/* ---------- Header ---------- */

.preview-header {
  background: var(--pv-surface);
  border-bottom: 1px solid var(--pv-border);
}

.preview-header-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 14px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.preview-header-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--pv-text);
  display: flex;
  align-items: center;
  gap: 8px;
}

.preview-back {
  color: var(--pv-text-soft);
  text-decoration: none;
  font-weight: 500;
}

.preview-back:hover { color: var(--pv-accent); }

.preview-divider {
  color: var(--pv-text-mute);
  font-weight: 300;
}

/* 헤더에서 링크가 아닌 브랜드명(뒤로가기 없는 단일지점/단일브랜드 화면). */
.preview-header-brand {
  color: var(--pv-text);
  font-weight: 600;
}

.preview-header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.preview-header-user {
  color: var(--pv-text-soft);
  font-size: 13px;
}

.preview-logout-form { margin: 0; }

/* ---------- Main / sections ---------- */

.preview-main {
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px 20px 64px;
}

.preview-section + .preview-section { margin-top: 32px; }

/* 페이지 타이틀 — 헤더 백바 아래, 프린트 잔량 위. 현재 지점(또는 브랜드)명. */
.preview-page-head { margin: 0 0 16px; }
.preview-page-title {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  color: var(--pv-text);
}

.preview-section-title {
  margin: 0 0 14px;
  font-size: 14px;
  font-weight: 600;
  color: var(--pv-text-soft);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.preview-empty {
  color: var(--pv-text-mute);
  font-size: 13px;
}

/* ---------- Brand list ---------- */

.preview-brand-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}

.preview-brand-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 14px;
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  box-shadow: var(--pv-shadow);
  text-decoration: none;
  color: var(--pv-text);
  transition: border-color 0.15s, transform 0.15s;
}

.preview-brand-card:hover {
  border-color: #d4d4dc;
  transform: translateY(-1px);
}

.preview-brand-swatch {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  flex: 0 0 auto;
}

/* [색상 | 정보] — 색 띠를 카드 왼쪽 끝까지 붙여 세운다.
   28px 견본은 줄마다 똑같아 세는 데 도움이 안 됐다. 띠로 세우면 번호를 크게
   쓸 자리가 생기고, 목록을 훑을 때 왼쪽 한 줄만 따라가면 된다.

   왼쪽·위아래 여백을 카드에서 걷어 내고 그만큼을 내용 쪽에 준다. 그래야 띠가
   테두리에 닿는다 — 여백을 남기면 '띠'가 아니라 '큰 사각형'이 된다. */
.preview-brand-card--bar {
  padding: 0 14px;
  overflow: hidden;          /* 띠의 모서리를 카드 둥근 모서리에 맞춰 자른다 */
}
.preview-brand-card--bar .preview-brand-swatch {
  align-self: stretch;       /* 카드 높이를 그대로 채운다 */
  width: 46px;
  height: auto;
  min-height: 58px;
  border-radius: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  /* 옅은 테마색 위에서도 읽히게. 배경이 밝은 브랜드가 있다. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, .3);
}
.preview-brand-card--bar .preview-brand-meta { padding: 14px 0; }

.preview-brand-meta { flex: 1 1 auto; min-width: 0; }
.preview-brand-name { font-weight: 600; font-size: 14px; }
/* 지점 코드는 고정폭을 쓸 이유가 없다 — 자릿수를 세거나 세로로 맞춰 보는 값이 아니다.
   본문과 같은 글꼴로 두어야 카드 안에서 두 줄이 같은 결로 읽힌다.
   (hash 처럼 한 글자씩 대조하는 값은 고정폭을 그대로 둔다) */
.preview-brand-code {
  color: var(--pv-text-soft); font-size: 12px;
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}

/* ---------- 총합 (브랜드 목록 위) ----------
   브랜드별 숫자만 있으면 "오늘 전체가 평소보다 적나"를 머리로 더해야 한다.
   통화가 섞이므로(스티커즈 국내 KRW + 중국 CNY) 합치지 않고 나란히 적는다. */
.preview-total { margin-bottom: 18px; }
.preview-total-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px; background: var(--pv-border);
  border: 1px solid var(--pv-border); border-radius: var(--pv-radius); overflow: hidden;
}
.preview-total-cell { background: var(--pv-surface); padding: 16px 18px; }
.preview-total-k {
  font-size: 11px; color: var(--pv-text-soft); letter-spacing: .03em; margin-bottom: 5px;
}
/* 통화마다 한 줄. 한 줄에 이어 붙였더니 좁은 화면에서 통째로 접혀 못 읽었다.
   국기가 어느 나라 돈인지 말해 준다 — ₩ 와 ¥ 는 서로 닮아서 기호만으로는 헷갈린다. */
.preview-total-v {
  display: flex; align-items: center; gap: 7px;
  font-size: 20px; font-weight: 700; color: var(--pv-text); line-height: 1.3;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.preview-total-v + .preview-total-v { margin-top: 2px; }
/* 국기는 흰 바탕(태극기·싱가포르)이 카드 흰색에 묻힌다. 옅은 그림자로 띄운다 —
   테두리만 두면 선이 하나 더 생겨 도안이 답답해 보인다. */
.preview-flag {
  display: block; flex-shrink: 0; border-radius: 2px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .16);
}
.preview-total-unit { font-size: 14px; font-weight: 500; color: var(--pv-text-soft); margin-left: 2px; }
.preview-total-n { margin-top: 3px; font-size: 12px; color: var(--pv-text-soft); }
.preview-total-n .is-bad { color: #b91c1c; font-weight: 600; }

/* ---------- 지점 목록 ----------
   브랜드 목록(preview-brand-grid)은 여러 칸으로 나누지만 지점 목록은 그러면 안 된다.
   220px 칸에 [번호][이름][매출][→] 을 밀어 넣었더니 이름이 한 글자씩 세로로 접혔다
   (2026-09-09 Funny 화면). 지점은 세로로 한 줄씩 쌓는다. */
.preview-store-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* 카드 높이를 맞춘다. 내용은 이름·코드·매출·상태 네 줄이 기준이고, 상태가 없어도
   그 자리는 비워 둔다. 높이가 제각각이면 목록을 훑을 때 눈이 멈추지 못한다. */
.preview-store-row { width: 100%; min-height: 116px; }
.preview-store-row .preview-brand-meta {
  display: flex; flex-direction: column; gap: 6px; padding: 16px 0;
}
.preview-store-row .preview-brand-name { font-size: 15px; line-height: 1.3; }
.preview-store-row .preview-brand-code { line-height: 1.3; }

/* 아래 한 줄 — 왼쪽 매출, 오른쪽 끝 기기 이상.
   이 화면은 지점 이름과 코드만 보여줬다. 어느 지점이 오늘 한 건도 못 팔았는지 보려면
   지점을 하나씩 눌러 들어가야 했고(스티커즈 52곳이면 52번), 그래서 아무도 안 봤다. */
.preview-store-bottom { margin-top: 4px; }
.preview-store-figs { display: flex; gap: 22px; align-items: baseline; flex-wrap: wrap; }
/* 통화가 여럿이면 값이 여러 개다. 세로로 쌓되 라벨은 첫 줄에 맞춘다. */
.preview-store-fig { display: flex; align-items: baseline; gap: 6px; min-height: 21px; }
.preview-store-fig .preview-store-fig-v { display: inline-flex; align-items: center; gap: 5px; }
.preview-store-fig .preview-flag { position: relative; top: 1px; }
.preview-store-fig-k { font-size: 11px; color: var(--pv-text-soft); letter-spacing: .02em; }
.preview-store-fig-v {
  font-size: 16px; font-weight: 600; color: var(--pv-text);
  font-variant-numeric: tabular-nums;
}
.preview-store-fig-n { font-size: 11px; color: var(--pv-text-soft); font-variant-numeric: tabular-nums; }
/* 오늘은 이번달 옆에 붙는 참고값이라 한 단계 죽인다 — 두 숫자가 같은 무게면
   눈이 어디를 볼지 모른다. */
.preview-store-fig--soft .preview-store-fig-v { font-size: 14px; font-weight: 500; color: var(--pv-text-soft); }
/* 오늘 0건에 경고색을 쓰지 않는다. 개점 전이거나 영업시간 밖일 수 있고,
   매일 빨간 화면은 아무도 안 본다. 판단은 옆의 이번달 값이 거든다. */
.preview-store-fig.is-zero .preview-store-fig-v { color: var(--pv-text-soft); }

/* 상태 줄 — 카드 맨 아래.
   매출 옆에 아이콘만 두었더니 무슨 이상인지 알려면 hover 해야 했고, 목록을 훑는
   화면에서는 아무도 hover 하지 않는다. 아이콘과 문구를 같이 낸다.

   여전히 **나쁠 때만** 뜬다. 정상까지 그리면 모든 카드에 한 줄이 더 붙어서
   정작 이상한 지점이 안 보인다. */
/* 상태 줄은 비어 있어도 자리를 지킨다. 있을 때만 그리면 카드 높이가 줄마다 달라져
   목록이 들쭉날쭉해지고, 그러면 어디를 봐야 할지 눈이 멈추지 못한다. */
.preview-store-marks {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  /* 30px — 프린터 고장 칩은 코드를 아래 줄에 달아 한 줄 칩보다 높다. 그 칩이 있는 카드만
     커지면 목록이 다시 들쭉날쭉해지므로 자리를 미리 잡는다. */
  margin-top: 8px; min-height: 30px;
}
.preview-store-mark {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px 4px 7px; border-radius: 999px;
  font-size: 12px; font-weight: 500; line-height: 1.2; white-space: nowrap;
}
.preview-store-mark[title] { cursor: help; }
/* 정상은 중립색이다. 초록으로 칠하면 다섯 칩이 다 초록이라 아무것도 안 도드라진다 —
   색은 "여기를 봐라"는 뜻이어야 한다. 나쁜 것만 색을 쓴다. */
.preview-store-mark.is-ok    { color: var(--pv-text-soft); background: #f1f3f5; }
.preview-store-mark.is-warn  { color: #92400e; background: #fef3c7; }
.preview-store-mark.is-fault { color: #991b1b; background: #fee2e2; }
/* 값을 못 받은 것(DEV·미연동)은 정상과 다르다. 점선으로 "모른다"를 표시한다. */
.preview-store-mark.is-mute  {
  color: var(--pv-text-soft); background: transparent;
  box-shadow: inset 0 0 0 1px var(--pv-border);
}
/* 미연동은 장애가 아니라 아직 안 붙은 것이다. 같은 붉은색으로 두면 배포가 안 끝난
   브랜드가 매일 경보로 뜨고, 그러면 아무도 안 본다. */
.preview-store-mark.is-mute { color: var(--pv-text-soft); background: #f1f3f5; }
/* 문구만 있는 알약(브랜드 목록)은 아이콘 자리를 비워 둘 필요가 없다. */
.preview-store-mark:not(:has(.preview-store-ico)) { padding: 4px 10px; }
.preview-store-ico { display: block; flex-shrink: 0; }
.preview-store-mark-t { display: inline-block; }
/* 프린터 고장 칩 — 원인은 색과 글자로, 제조사 코드는 아래 줄에 작게. 코드는 앱·AS 와
   대화할 때 보는 값이라 원인만큼 크게 둘 이유가 없다. */
.preview-store-mark-code {
  display: block; font-size: 10px; font-weight: 400; line-height: 1.1;
  opacity: .75; font-variant-numeric: tabular-nums;
}
.preview-store-mark:has(.preview-store-mark-code) {
  border-radius: 10px; padding-top: 2px; padding-bottom: 2px;
}

@media (max-width: 560px) {
  .preview-store-figs { gap: 14px; }
  .preview-store-mark { font-size: 11px; padding: 3px 8px 3px 6px; }
}

.preview-brand-cta {
  color: var(--pv-text-soft);
  font-size: 28px;
  line-height: 1;
  font-weight: 300;
  flex-shrink: 0;
  padding-left: 4px;
  transition: transform 0.15s ease, color 0.15s ease;
}
.preview-brand-card:hover .preview-brand-cta {
  color: var(--pv-text);
  transform: translateX(4px);
}

/* ---------- Grid toolbar ---------- */

.preview-filter-card {
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  box-shadow: var(--pv-shadow);
  padding: 14px;
  margin-bottom: 16px;
}

.preview-date-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 10px;
  margin-bottom: 12px;
}

.preview-date-actions {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.preview-date-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  color: var(--pv-text-soft);
  font-size: 12px;
  font-weight: 600;
}

.preview-date-field input {
  min-width: 150px;
  padding: 8px 10px;
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  background: var(--pv-surface);
  color: var(--pv-text);
  font-size: 13px;
}

.preview-booth-filter {
  display: grid;
  gap: 8px;
  margin: 0 0 12px;
}
/* 부스 2개 미만이면 JS가 hidden 처리 — display:grid가 [hidden]을 덮지 않게 명시. */
.preview-booth-filter[hidden] { display: none; }

.preview-booth-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.preview-booth-card {
  position: relative;
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  background: var(--pv-surface);
  color: var(--pv-text);
  padding: 12px 14px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  min-width: 0;
  text-align: left;
  font: inherit;
  box-shadow: var(--pv-shadow);
  transition: border-color .15s, background .15s;
}
.preview-booth-card:hover { border-color: #c9c9d1; }
.preview-booth-card--all { width: 100%; padding: 14px 16px; }

.preview-booth-name {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
  word-break: keep-all;
  min-width: 0;
}
/* 부스 번호는 위 줄에 작고 옅게, 이름은 아래 줄에 다 보이게(잔량 카드와 같은 결) */
.preview-booth-name .preview-booth-code { display: block; margin: 0 0 1px; }
.preview-booth-code {
  margin-right: 6px;
  font-size: 11px;
  font-weight: 600;
  color: var(--pv-text-mute);
}

/* 금액이 주인공, 건수·비중은 한 줄 아래 작게 */
.preview-booth-revenue {
  margin-top: 4px;
  font-size: 17px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.preview-booth-sub {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  font-weight: 500;
  color: var(--pv-text-soft);
}
.preview-booth-share { font-weight: 700; color: var(--pv-text); }

/* 전체 매출 중 이 부스 비중 */
.preview-booth-bar {
  display: block;
  height: 4px;
  margin-top: 8px;
  border-radius: 2px;
  background: var(--pv-bg);
  overflow: hidden;
}
.preview-booth-bar i { display: block; height: 100%; border-radius: 2px; background: var(--pv-accent); }

.preview-booth-card--all .preview-booth-name { font-size: 14px; }
.preview-booth-card--all .preview-booth-revenue { font-size: 24px; }

/* 선택된 카드 — 검은 박스 */
.preview-booth-card.is-active { background: var(--pv-text); border-color: var(--pv-text); color: #fff; }
.preview-booth-card.is-active .preview-booth-code { color: rgba(255, 255, 255, 0.55); }
.preview-booth-card.is-active .preview-booth-sub { color: rgba(255, 255, 255, 0.7); }
.preview-booth-card.is-active .preview-booth-share { color: #fff; }
.preview-booth-card.is-active .preview-booth-bar { background: rgba(255, 255, 255, 0.18); }
.preview-booth-card.is-active .preview-booth-bar i { background: #fff; }

@media (max-width: 640px) {
  .preview-date-actions {
    width: 100%;
    margin-left: 0;
    justify-content: flex-end;
  }
  .preview-booth-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.preview-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
@media (min-width: 720px) {
  .preview-summary {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.preview-summary-metric {
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  padding: 10px 12px;
}

.preview-summary-label {
  display: block;
  color: var(--pv-text-soft);
  font-size: 11px;
  margin-bottom: 4px;
}

.preview-summary-metric strong {
  display: block;
  color: var(--pv-text);
  font-size: 20px;
  font-weight: 700;
}

.preview-summary-metric--revenue strong {
  color: var(--pv-accent);
}

.preview-summary-frames {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}

.preview-frame-summary {
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  padding: 8px 10px;
}

.preview-frame-summary-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.preview-frame-summary-labels {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.preview-frame-tag {
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--pv-bg);
  border: 1px solid var(--pv-border);
  color: var(--pv-text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
}

.preview-frame-summary-labels span {
  color: var(--pv-text-soft);
  font-size: 12px;
}

.preview-frame-total,
.preview-frame-revenue {
  color: var(--pv-text);
  font-size: 15px;
  font-weight: 700;
  white-space: nowrap;
}

.preview-summary-empty,
.preview-summary-note {
  color: var(--pv-text-mute);
  font-size: 12px;
}

.preview-summary-note {
  margin: 10px 0 0;
}

/* Kiosk supply strip — sits above the grid toolbar. One chip per deviceCode
   showing the latest paperRemain. The wrapper auto-hides (including the
   "프린트 잔량" heading) when the strip has no rows. */
.preview-kiosks-wrap {
  margin-bottom: 14px;
}
.preview-kiosks-wrap:has(.preview-kiosks-strip:empty) {
  display: none;
}
.preview-kiosks-title {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--pv-text-soft);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.preview-kiosks-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.preview-kiosk-chip {
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  padding: 8px 10px;
  text-align: center;
  box-shadow: var(--pv-shadow);
}
.preview-kiosk-chip-id {
  font-size: 11px;
  color: var(--pv-text-soft);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  margin-bottom: 2px;
}
.preview-kiosk-chip-remain {
  font-size: 18px;
  font-weight: 600;
  color: var(--pv-text);
  line-height: 1.1;
}
/* 기기 상태 — AOBSC 하트비트. 접이식 한 줄 표.
   격자 카드로 두었더니 기기가 많은 브랜드(gkpb24 46대)에서 화면 절반을 먹었다.
   평소엔 접어 두고 요약만 보이게 하고, 펼치면 한 기기가 한 줄이다. */
.preview-devices-wrap { margin-bottom: 14px; }
.preview-devices-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: var(--pv-surface); border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm); padding: 8px 12px;
  font: inherit; color: var(--pv-text); cursor: pointer; text-align: left;
}
.preview-devices-title {
  font-size: 12px; font-weight: 600; color: var(--pv-text-soft);
  letter-spacing: 0.02em; text-transform: uppercase;
}
.preview-devices-sum { font-size: 12px; color: var(--pv-text-soft); }
.preview-devices-sum.is-warn { color: #b45309; font-weight: 600; }
.preview-devices-chev { margin-left: auto; color: var(--pv-text-soft); font-size: 11px; }
.preview-devices-head[aria-expanded="true"] .preview-devices-chev { transform: rotate(180deg); }
.preview-devices-body { margin-top: 6px; }
/* 컬럼이 여덟이라 좁은 화면에서는 가로로 굴린다. 페이지 자체가 밀리면 안 된다. */
.preview-dev-scroll { overflow-x: auto; }
.preview-dev-table {
  width: 100%; border-collapse: collapse; font-size: 12px;
  background: var(--pv-surface); border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
}
.preview-dev-table th, .preview-dev-table td {
  padding: 5px 8px; text-align: center; white-space: nowrap;
  border-bottom: 1px solid var(--pv-border);
}
.preview-dev-table thead th {
  font-size: 11px; font-weight: 500; color: var(--pv-text-soft);
  background: var(--pv-bg, #fafafa); cursor: help; padding: 6px 8px;
}
/* 아이콘 머리 — 이모지는 OS 마다 크기가 달라 정렬이 흔들렸다. SVG 로 못박는다. */
.preview-dev-ico { display: block; margin: 0 auto; }
.preview-dev-table tbody tr:last-child td { border-bottom: 0; }
.preview-dev-table td.preview-dev-id, .preview-dev-table th.preview-dev-id {
  text-align: left; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
}
.preview-dev-table td.preview-dev-name, .preview-dev-table th.preview-dev-name {
  text-align: left; max-width: 130px; overflow: hidden;
  text-overflow: ellipsis; font-size: 11px;
}
/* 생사는 색 점 하나로. 줄 전체를 물들이면 여덟 칸이 다 붉어져 정작 어느 값이
   문제인지 안 보인다. */
.preview-dev-dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  margin-right: 5px; vertical-align: middle; background: #9ca3af;
}
.preview-dev-row--online .preview-dev-dot { background: #16a34a; }
.preview-dev-row--stale  .preview-dev-dot { background: #f59e0b; }
.preview-dev-row--stale  { background: #fffbf5; }
/* 한 번도 안 보낸 기기는 장애가 아니라 아직 안 붙은 것이라 조용히 둔다. */
.preview-dev-row--never  { opacity: 0.5; }
.preview-dev-row--never .preview-dev-dot { background: transparent; box-shadow: inset 0 0 0 1px #9ca3af; }
/* 영업시간 밖에 꺼진 기기 — 장애가 아니라 퇴근이다. 조용히 흐리게만 둔다. */
.preview-dev-row--closed { opacity: 0.6; }
.preview-dev-row--closed .preview-dev-dot { background: #cbd5e1; }
/* 지점 카드 코드 옆 영업시간. 지금 영업시간 밖이면 더 흐리게. */
.preview-store-hours { color: var(--pv-text-soft); cursor: help; }
.preview-store-hours.is-closed { opacity: .6; }
/* 끊긴 줄의 '마지막 신호'는 그 자체가 장애 시간이라 그 칸만 강조한다. */
.preview-dev-late { color: #b45309; font-weight: 600; }
/* 프린터 칸 — 고장 원인은 색으로 가르고 제조사 코드는 아래 줄에 작게 둔다.
   고장(인쇄가 멈춤)은 빨강, 주의(용지·리본 부족, 냉각)는 호박. 지점 카드 칩과 같은 색이다. */
.preview-dev-state { font-weight: 600; }
.preview-dev-state.is-fault { color: #b91c1c; }
.preview-dev-state.is-warn  { color: #b45309; }
.preview-dev-code {
  display: block; font-size: 10px; line-height: 1.1; margin-top: 1px;
  color: var(--pv-text-soft); font-variant-numeric: tabular-nums;
}
.preview-devices-note { margin-top: 6px; font-size: 11px; color: var(--pv-text-soft); }
.preview-devices-note:empty { display: none; }

.preview-kiosk-chip--low {
  border-color: #fecdd3;
  background: #fff8f8;
}
.preview-kiosk-chip--low .preview-kiosk-chip-remain {
  color: var(--pv-danger);
}

.preview-grid-toolbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.preview-grid-toolbar > #preview-load-new {
  grid-column: 2;
  justify-self: center;
}

.preview-grid-status {
  color: var(--pv-text-soft);
  font-size: 13px;
}

#preview-count {
  color: var(--pv-text);
  font-weight: 600;
}

/* ---------- Cards grid ---------- */

.preview-grid {
  display: grid;
  /* Mobile-first: lock to 2 columns so phones don't fall back to a single
     wide card that wastes vertical space. minmax(0, 1fr) keeps card content
     from blowing the column out at narrow widths. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
@media (min-width: 640px) {
  .preview-grid {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 14px;
  }
}

.preview-card {
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  box-shadow: var(--pv-shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.preview-card-thumb {
  aspect-ratio: 1 / 1;
  background: #f0f0f3;
  overflow: hidden;
  position: relative;
}

.preview-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.preview-card-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  background: rgba(20, 20, 30, 0.7);
  color: #fff;
  font-size: 11px;
  padding: 2px 7px;
  border-radius: 999px;
}

.preview-card-booth-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  background: rgba(20, 20, 30, 0.78);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 2px 8px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}

.preview-card-body {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 카드 본문은 한 줄에 하나씩 세운다. 두 값을 좌우로 밀어 넣으면 좁은
   카드에서 접혀 카드 높이가 들쭉날쭉해진다(실측: "삭제까지 21시간 남음"이
   두 줄로 꺾였다). */
.preview-card-line {
  font-size: 12px;
  line-height: 1.4;
  color: var(--pv-text-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-card-hash {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--pv-text);
}

/* 촬영 시각 — 상대시간만으로는 언제 찍었는지 알 수 없다. */
.preview-card-shot { color: var(--pv-text); }
.preview-card-ago { color: var(--pv-text-mute); font-size: 11px; }

.preview-card-expires {
  font-size: 11px;
  color: var(--pv-text-mute);
}

.preview-card-actions {
  display: flex;
  gap: 6px;
  margin-top: 2px;
}
.preview-card-actions .preview-card-button { flex: 1 1 auto; }
.preview-card-more {
  flex: 0 0 auto;
  padding: 8px 10px;
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  color: var(--pv-text-soft);
  font-size: 12px;
  cursor: pointer;
}
.preview-card-more:hover { background: #fafafb; border-color: #d4d4dc; }
.preview-card-more:disabled { opacity: .5; cursor: default; }

.preview-card-print {
  margin: 0 0 8px;
  padding: 4px 8px;
  background: var(--pv-bg);
  border-radius: var(--pv-radius-sm);
  font-size: 11px;
  color: var(--pv-text-soft);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  text-align: center;
}

.preview-card-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 10px;
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  color: var(--pv-text);
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}

.preview-card-button:hover {
  background: #fafafb;
  border-color: #d4d4dc;
}

/* ---------- Grid footer ---------- */

.preview-grid-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 24px;
}

.preview-grid-footer .preview-btn--primary {
  width: auto;
  min-width: 200px;
}

.preview-status {
  margin: 0;
  color: var(--pv-text-mute);
  font-size: 12px;
}

/* ---------- Admin (Phase 2) ---------- */

.preview-flash {
  margin: 0 0 16px;
  padding: 10px 14px;
  border-radius: var(--pv-radius-sm);
  font-size: 13px;
  border: 1px solid var(--pv-border);
}
.preview-flash--ok {
  background: #ecfdf5;
  border-color: #a7f3d0;
  color: #047857;
}
.preview-flash--err {
  background: #fff1f2;
  border-color: #fecdd3;
  color: var(--pv-danger);
}

.preview-admin-table-wrap {
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  box-shadow: var(--pv-shadow);
  overflow-x: auto;
}

.preview-admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.preview-admin-table th,
.preview-admin-table td {
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--pv-border);
  vertical-align: middle;
}

.preview-admin-table thead th {
  background: #fafafb;
  color: var(--pv-text-soft);
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.preview-admin-table tbody tr:last-child td { border-bottom: none; }

.preview-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--pv-text);
}

.preview-admin-ts { color: var(--pv-text-soft); font-size: 12px; }

.preview-admin-self {
  color: var(--pv-text-mute);
  font-size: 12px;
  font-style: italic;
}

.preview-admin-inline-form {
  display: flex;
  gap: 6px;
  align-items: center;
  margin: 0;
}

.preview-admin-inline-form input[type="password"] {
  padding: 6px 8px;
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  font-size: 12px;
  width: 140px;
  outline: none;
}
.preview-admin-inline-form input[type="password"]:focus {
  border-color: var(--pv-accent);
}

.preview-btn--danger {
  color: var(--pv-danger);
  border-color: #fecdd3;
}
.preview-btn--danger:hover {
  background: #fff1f2;
  border-color: var(--pv-danger);
}

.preview-admin-create {
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  box-shadow: var(--pv-shadow);
  padding: 18px 18px 20px;
  max-width: 520px;
}

.preview-admin-create .preview-field input,
.preview-admin-create .preview-field select {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
  font-size: 14px;
  background: var(--pv-surface);
  color: var(--pv-text);
  outline: none;
  transition: border-color 0.15s;
}
.preview-admin-create .preview-field input:focus,
.preview-admin-create .preview-field select:focus {
  border-color: var(--pv-accent);
}

.preview-admin-create .preview-btn--primary {
  width: auto;
  min-width: 160px;
  margin-top: 4px;
}

.preview-admin-hint {
  margin: 4px 0 16px;
  color: var(--pv-text-mute);
  font-size: 12px;
}

.preview-checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 8px;
  padding: 10px 12px;
  background: var(--pv-bg);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm);
}

.preview-checkbox-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--pv-text);
  cursor: pointer;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.preview-checkbox-item input {
  margin: 0;
  cursor: pointer;
}

/* ===== 상단 탭 (매출/현황 ↔ 프리뷰) ===== */
.preview-tabs {
  display: flex;
  gap: 4px;
  margin: 16px 0 0;
  border-bottom: 1px solid var(--pv-border);
}
.preview-tab {
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 10px 18px;
  font-size: 15px;
  color: var(--pv-text-soft);
  cursor: pointer;
}
.preview-tab.is-active {
  color: var(--pv-accent);
  border-bottom-color: var(--pv-accent);
  font-weight: 600;
}
.preview-panel { margin-top: 16px; }
.preview-panel[hidden] { display: none; }

/* ===== 매출 탭 달력 ===== */
.preview-calendar-card {
  margin-top: 18px;
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  padding: 14px;
}
.preview-cal-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.preview-cal-label { font-size: 15px; font-weight: 600; }
.preview-cal-total { margin-left: auto; font-size: 13px; color: var(--pv-text-soft); }
.preview-cal-clear {
  appearance: none; cursor: pointer;
  border: 1px solid var(--pv-accent); background: var(--pv-accent); color: #fff;
  border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 600;
}
.preview-cal-clear:hover { background: var(--pv-accent-hover); border-color: var(--pv-accent-hover); }
.preview-calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.preview-cal-dow {
  text-align: center;
  font-size: 12px;
  color: var(--pv-text-mute);
  padding: 4px 0;
}
.preview-cal-cell {
  appearance: none;
  text-align: left;
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: 8px;
  min-height: 62px;
  padding: 6px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* 셀 너비 기준 유동 폰트(cqw) — 금액이 셀 폭에 맞춰 자동 축소 */
  container-type: inline-size;
  overflow: hidden;
}
.preview-cal-cell--empty { background: transparent; border: 0; cursor: default; }
.preview-cal-cell:not(.preview-cal-cell--empty):hover { border-color: var(--pv-accent); }
.preview-cal-cell.has-sales { background: #f6f9ff; }
.preview-cal-cell.is-selected { border-color: var(--pv-accent); box-shadow: 0 0 0 1px var(--pv-accent) inset; }
/* 날짜·금액·건수: 셀 너비(cqw)에 비례해 자동 축소 — 7자리 금액도 항상 셀 안에 맞음.
   17cqw ≈ 셀 폭의 17%, 데스크탑은 12px 상한, 초소형은 5px 하한으로 클램프 */
.preview-cal-dnum { font-size: 9px; font-size: clamp(5px, 17cqw, 12px); color: var(--pv-text-soft); line-height: 1.1; }
.preview-cal-amt { font-size: 8px; font-size: clamp(5px, 17cqw, 12px); font-weight: 700; color: var(--pv-accent); margin-top: auto; white-space: nowrap; font-variant-numeric: tabular-nums; letter-spacing: -0.2px; line-height: 1.1; }
/* 축약(141만) 대신 정확한 값(1,407,000)을 쓰므로 자릿수가 길다. 값을 뭉개는 대신
   글자를 줄인다 — 자릿수 구간별로 셀 폭 대비 비율(cqw)과 상·하한을 낮춘다.
   JS(grid.js calAmountClass)가 문자열 길이를 보고 클래스를 붙인다. */
.preview-cal-amt.is-w9  { font-size: clamp(4px, 11.5cqw, 9px); letter-spacing: -0.3px; }
.preview-cal-amt.is-w12 { font-size: clamp(3.5px, 9cqw, 8px); letter-spacing: -0.4px; }
/* 건수는 금액보다 한 단계 작게 — 금액이 축약을 버리고 길어진 만큼, 셀 안에서
   읽는 순서(금액 먼저)가 드러나도록 위계를 준다. */
.preview-cal-cnt { font-size: 8px; font-size: clamp(4.5px, 14cqw, 10px); color: var(--pv-text-mute); line-height: 1.1; }

@media (max-width: 520px) {
  .preview-calendar { gap: 3px; }
  .preview-cal-dow { font-size: 10px; padding: 2px 0; }
  .preview-cal-cell { min-height: 46px; padding: 3px; border-radius: 6px; }
  .preview-cal-label { font-size: 14px; }
  .preview-cal-total { font-size: 11px; }
}
@media (max-width: 380px) {
  .preview-cal-cell { min-height: 40px; padding: 2px; }
}

/* ===== 매출 탭 KPI (이번달/오늘 매출) ===== */
.preview-kpi {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}
.preview-kpi-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--pv-surface);
  border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius);
  padding: 14px 18px;
}
.preview-kpi-label { font-size: 14px; color: var(--pv-text-soft); }
.preview-kpi-value { font-size: 22px; font-weight: 700; color: var(--pv-accent); font-variant-numeric: tabular-nums; }

/* ===== 날짜 3모드 + 커스텀 범위 ===== */
.preview-date-modes { display: flex; gap: 6px; margin-bottom: 10px; }
.preview-mode-btn {
  appearance: none; border: 1px solid var(--pv-border); background: var(--pv-surface);
  border-radius: 999px; padding: 7px 16px; font-size: 14px; color: var(--pv-text-soft); cursor: pointer;
}
.preview-mode-btn.is-active { background: var(--pv-accent); border-color: var(--pv-accent); color: #fff; font-weight: 600; }
.preview-date-custom {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 12px;
  padding: 12px; background: var(--pv-bg); border: 1px solid var(--pv-border); border-radius: var(--pv-radius-sm);
}
.preview-date-custom[hidden] { display: none; }
.preview-date-custom input[type="date"] {
  flex: 1 1 auto; min-width: 130px; padding: 8px 10px;
  border: 1px solid var(--pv-border); border-radius: var(--pv-radius-sm);
  background: var(--pv-surface); color: var(--pv-text); font-size: 13px;
}
.preview-date-custom input[type="date"]:focus { border-color: var(--pv-accent); outline: none; }
.preview-date-custom .preview-btn--primary { width: auto; flex: 0 0 auto; padding: 8px 20px; }
.preview-date-tilde { color: var(--pv-text-mute); flex: 0 0 auto; }

/* ===== 결제수단 4탭 ===== */
.preview-pay { margin-top: 16px; background: var(--pv-surface); border: 1px solid var(--pv-border); border-radius: var(--pv-radius); padding: 12px; }
.preview-pay-tabs { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--pv-border); padding-bottom: 8px; }
.preview-pay-tab {
  appearance: none; border: 0; background: transparent; border-radius: 8px;
  padding: 6px 12px; font-size: 13px; color: var(--pv-text-soft); cursor: pointer;
}
.preview-pay-tab.is-active { background: var(--pv-accent); color: #fff; font-weight: 600; }
.preview-pay-tab-cnt { opacity: .8; font-size: 12px; }
.preview-pay-body { display: flex; gap: 24px; padding: 12px 4px 2px; }
.preview-pay-metric { display: flex; flex-direction: column; gap: 2px; }
.preview-pay-metric span { font-size: 12px; color: var(--pv-text-soft); }
.preview-pay-metric strong { font-size: 18px; font-variant-numeric: tabular-nums; }

/* ===== 시간대별 (접이식) ===== */
.preview-hourly-card { margin-top: 16px; background: var(--pv-surface); border: 1px solid var(--pv-border); border-radius: var(--pv-radius); padding: 12px; }
.preview-hourly-title { font-size: 14px; margin: 0 0 8px; color: var(--pv-text); }
.preview-hour-row { border-top: 1px solid var(--pv-border); }
.preview-hour-row:first-child { border-top: 0; }
.preview-hour-head {
  width: 100%; appearance: none; border: 0; background: transparent; cursor: pointer;
  display: flex; align-items: center; gap: 10px; padding: 10px 4px; font-size: 14px; text-align: left;
}
.preview-hour-label { font-weight: 600; min-width: 44px; }
.preview-hour-sum { color: var(--pv-text-soft); }
.preview-hour-caret { margin-left: auto; color: var(--pv-text-mute); transition: transform .12s; }
.preview-hour-head.is-open .preview-hour-caret { transform: rotate(180deg); }
.preview-hour-items { padding: 0 4px 10px; }
.preview-hour-items[hidden] { display: none; }
.preview-hour-item { display: flex; align-items: center; gap: 12px; padding: 5px 8px; font-size: 13px; border-radius: 6px; }
.preview-hour-item:nth-child(odd) { background: var(--pv-bg); }
.preview-hour-time { font-variant-numeric: tabular-nums; color: var(--pv-text-soft); min-width: 72px; }
.preview-hour-frame { flex: 1; color: var(--pv-text); }
.preview-hour-amt { font-variant-numeric: tabular-nums; font-weight: 600; }
.preview-hour-more { font-size: 12px; color: var(--pv-text-mute); padding: 6px 8px; }

/* ===== 결제 내역 리스트 (최신순) ===== */
.preview-txn-card { margin-top: 16px; background: var(--pv-surface); border: 1px solid var(--pv-border); border-radius: var(--pv-radius); padding: 12px; }
.preview-txn-title { font-size: 14px; margin: 0 0 8px; color: var(--pv-text); }
.preview-txn-list { display: flex; flex-direction: column; }
.preview-txn-row {
  /* 칸 수와 셀 수가 어긋나면 마지막 셀이 다음 줄로 떨어져 행이 두 겹이 된다.
     시각·부스·프레임·결제수단·금액·세로점 여섯을 그대로 센다. */
  display: grid;
  /* 시각 칸은 글자 폭에 딱 맞춘다. 넉넉히 잡아 두면 남는 자리가 그대로 빈
     여백이 되어, 정작 길어질 수 있는 프레임·조치 칸이 먼저 잘린다.
     행마다 grid 라 auto 를 쓰면 열이 안 맞아 고정폭이어야 한다. */
  grid-template-columns: 100px 40px minmax(0, 1fr) auto auto 20px;
  align-items: center; gap: 6px;
  padding: 8px; font-size: 13px; border-top: 1px solid var(--pv-border);
}
/* 시각은 절대 접히면 안 된다. 접히는 순간 행 높이가 두 배가 된다. */
.preview-txn-time { white-space: nowrap; }
.preview-txn-row:first-child { border-top: 0; }
.preview-txn-row:nth-child(even) { background: var(--pv-bg); }

/* 취소 행 — 금액이 음수라 눈에 띄지만, 목록을 훑을 때 색으로 먼저 잡히게 한다.
   짝수행 배경(nth-child)보다 뒤에 와야 덮인다. */
.preview-txn-row.is-cancel,
.preview-txn-row.is-cancel:nth-child(even) { background: #fef2f2; }
.preview-txn-row.is-cancel .preview-txn-amt,
.preview-txn-row.is-cancel .preview-txn-method { color: #b91c1c; font-weight: 600; }
/* 취소 행의 프레임 칸에는 원거래 참조가 들어간다. 빨강까지 입히면 그것도
   경고로 읽히는데, 그건 안내지 경고가 아니다. */
.preview-txn-row.is-cancel .preview-txn-frame {
  color: #9a6b6b; font-size: 11px;
}

/* 사진이 아직 없는 행 — 세 단계다. 색은 "지금 손봐야 하는가"만 말한다.
     촬영중     0~7분   손님이 아직 부스에 있다. 정상이므로 **색을 주지 않는다**
     업로드 대기 7~30분  촬영은 끝났을 시간인데 안 온다. 옅은 노랑
     사진 지연   30분~   손볼 일. 진한 노랑 (배너가 세는 구간)
   촬영중까지 노랑으로 칠하면 하루 종일 노란 행이 깔려, 정작 볼 것이 묻힌다.
   짝수행 배경(nth-child)보다 뒤에 와야 덮인다. */
.preview-txn-row.is-photo-shooting .preview-txn-frame {
  color: var(--pv-text-mute); font-size: 11px;
}
.preview-txn-row.is-photo-pending,
.preview-txn-row.is-photo-pending:nth-child(even) { background: #fefce8; }
.preview-txn-row.is-photo-pending .preview-txn-frame { color: #a16207; font-weight: 600; }
.preview-txn-row.is-photo-late,
.preview-txn-row.is-photo-late:nth-child(even) { background: #fef3c7; }
.preview-txn-row.is-photo-late .preview-txn-frame { color: #b45309; font-weight: 700; }

/* 조치완료 — 노랑을 내리고 옅은 회색으로 가라앉힌다. 사진은 여전히 안 왔지만
   사람이 끝냈으니 더 붙잡을 일이 아니다. 흔적은 체크로 남는다. */
.preview-txn-row.is-photo-done,
.preview-txn-row.is-photo-done:nth-child(even) { background: var(--pv-bg); }
.preview-txn-row.is-photo-done .preview-txn-time,
.preview-txn-row.is-photo-done .preview-txn-booth,
.preview-txn-row.is-photo-done .preview-txn-frame { color: var(--pv-text-mute); }

/* 정상 건에 조치만 붙은 경우 — 배경은 건드리지 않는다. 색을 주면 멀쩡한 거래가
   문제처럼 보인다. 체크 아이콘만으로 충분하다. */
.preview-txn-row.has-action .preview-txn-frame { color: var(--pv-text); }

/* 조치 행은 '오류 › 조치' 두 마디가 들어가 길다. 글자를 줄여 한 줄을 지킨다 —
   접히면 행 높이가 두 배가 되고, 그러면 목록을 훑는 눈이 끊긴다. */
.preview-txn-row.has-action .preview-txn-frame,
.preview-txn-row.is-photo-done .preview-txn-frame {
  font-size: 11px; letter-spacing: -0.2px;
}

/* 체크 아이콘 — 색을 갖지 않는다. 글자색을 그대로 따라가므로 회색 행에서는
   회색으로 가라앉고, 일반 행에서는 본문색이 된다. */
.preview-txn-check {
  display: inline-block; vertical-align: -1px; margin-right: 2px; flex: none;
}

/* 사진 대기 행은 행 전체가 눌린다 — 작은 세로점을 겨냥하지 않아도 되게. */
.preview-txn-row.is-photo-pending,
.preview-txn-row.is-photo-late,
.preview-txn-row.is-photo-done { cursor: pointer; }

/* ── 상세 탭 ───────────────────────────────────────────────────────
   사진·내역·조치를 한 화면에 세로로 쌓으면 스크롤이 길어져 아래 것이 안 보인다.
   탭으로 갈라 한 번에 하나만 보이게 한다. */
.preview-ovl-tabs {
  display: flex; gap: 2px; margin-bottom: 12px;
  border-bottom: 1px solid var(--pv-border);
}
.preview-ovl-tab {
  flex: 1 1 0; padding: 8px 4px; border: 0; background: none;
  color: var(--pv-text-mute); font-size: 13px; font-weight: 600; cursor: pointer;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.preview-ovl-tab.is-on { color: var(--pv-text); border-bottom-color: #1f2937; }
/* 탭 내용은 높이가 제각각이다. 최소 높이를 줘야 탭을 옮길 때 상자가 덜 튄다. */
.preview-ovl-panel { min-height: 150px; }

/* ── 조치 기록 ─────────────────────────────────────────────────────── */
.preview-ovl-action {
  margin-top: 16px; padding: 12px; border: 1px solid var(--pv-border);
  border-radius: 8px; background: var(--pv-bg);
}
.preview-ovl-action.is-done { background: #f0fdf4; border-color: #bbf7d0; }
.preview-ovl-action-head {
  font-size: 12px; font-weight: 700; color: var(--pv-text); margin-bottom: 8px;
}
.preview-ovl-action-label {
  font-size: 11px; font-weight: 700; color: var(--pv-text-mute);
  margin: 0 0 6px; letter-spacing: .02em;
}
.preview-ovl-tags + .preview-ovl-action-label { margin-top: 12px; }
.preview-ovl-action-sum {
  display: grid; grid-template-columns: 44px 1fr; gap: 4px 10px;
  margin: 0 0 8px; font-size: 13px;
}
.preview-ovl-action-sum dt { color: var(--pv-text-mute); }
.preview-ovl-action-sum dd { margin: 0; color: var(--pv-text); font-weight: 600; }
.preview-ovl-action.is-done .preview-ovl-action-head { color: #15803d; }
.preview-ovl-action-head .preview-txn-check { vertical-align: -1px; margin-right: 3px; }
.preview-ovl-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.preview-ovl-tag {
  padding: 6px 10px; border: 1px solid var(--pv-border); border-radius: 999px;
  background: #fff; color: var(--pv-text); font-size: 12px; cursor: pointer;
}
.preview-ovl-tag.is-on {
  background: #1f2937; border-color: #1f2937; color: #fff; font-weight: 600;
}
.preview-ovl-note {
  width: 100%; padding: 8px; border: 1px solid var(--pv-border); border-radius: 6px;
  font-size: 13px; margin-bottom: 8px; background: #fff; color: var(--pv-text);
}
.preview-ovl-action-save {
  width: 100%; padding: 9px; border: 1px solid #1f2937; border-radius: 8px;
  background: #1f2937; color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
}
.preview-ovl-action-save:disabled {
  background: var(--pv-bg); border-color: var(--pv-border);
  color: var(--pv-text-mute); cursor: default;
}
.preview-ovl-action-note { margin: 0 0 6px; font-size: 13px; color: var(--pv-text); }
.preview-ovl-action-by { margin: 0 0 8px; font-size: 11px; color: var(--pv-text-mute); }
.preview-ovl-action-clear {
  padding: 5px 10px; border: 1px solid var(--pv-border); border-radius: 6px;
  background: #fff; color: var(--pv-text-mute); font-size: 12px; cursor: pointer;
}

/* 취소된 결제 — 짝이 되는 음수 행이 어딘가에 있어 합계는 0이다.
   금액만 줄을 긋는다. 행 전체를 흐리면 목록을 훑을 때 존재 자체가 사라진다. */
.preview-txn-row.is-voided .preview-txn-amt {
  text-decoration: line-through; color: var(--pv-text-mute); font-weight: 600;
}

/* 짝으로 건너뛰는 버튼. 값 자리에 들어가므로 링크처럼 보이되 줄바꿈은 막는다. */
.preview-ovl-mate {
  padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--pv-accent, #2563eb); font: inherit; text-align: left;
  text-decoration: underline; white-space: nowrap;
}
.preview-ovl-mate:disabled { opacity: .5; cursor: default; }

/* 취소 버튼 — 눈에 띄되 먼저 잡히지는 않게. 실수로 누르는 자리가 아니다. */
.preview-txn-cancel {
  margin-left: 8px; padding: 2px 8px; font-size: 12px; line-height: 18px;
  border: 1px solid #fca5a5; border-radius: 6px; background: #fff; color: #b91c1c;
  cursor: pointer; white-space: nowrap;
}
.preview-txn-cancel:hover { background: #fef2f2; }
.preview-txn-cancel:disabled { opacity: .5; cursor: default; }
/* 행 끝 세로점 — 자리를 거의 안 차지해야 목록이 한 줄로 유지된다. */
.preview-txn-menu {
  width: 22px; flex: 0 0 22px; padding: 0; margin-left: 4px;
  border: 0; background: none; color: var(--pv-muted, #9ca3af);
  font-size: 16px; line-height: 1; cursor: pointer; text-align: center;
}
.preview-txn-menu:hover { color: var(--pv-text, #111827); }
.preview-txn-menu.is-empty { cursor: default; }

/* 거래 상세 */
.preview-ovl {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(0, 0, 0, .35);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.preview-ovl[hidden] { display: none; }
.preview-ovl-box {
  position: relative; width: 100%; max-width: 360px;
  background: #fff; border-radius: 12px; padding: 20px 18px 18px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .18);
  /* 사진이 들어가면 세로가 길어진다. 화면 밖으로 밀리면 취소 버튼에 닿지 못한다. */
  max-height: calc(100vh - 32px); overflow-y: auto;
}
.preview-ovl-close {
  position: absolute; top: 6px; right: 8px; width: 32px; height: 32px;
  border: 0; background: none; font-size: 22px; line-height: 1;
  color: var(--pv-muted, #9ca3af); cursor: pointer;
}
.preview-ovl-title { margin: 0 0 12px; font-size: 15px; font-weight: 700; }
.preview-ovl-list {
  display: grid; grid-template-columns: 84px 1fr; gap: 6px 10px;
  margin: 0; font-size: 13px;
}
.preview-ovl-list dt { color: var(--pv-muted, #6b7280); }
.preview-ovl-list dd { margin: 0; word-break: break-all; }
/* 결제 정보 — 승인번호·카드 상세. 거래 내역과 한 칸 띄워 구분한다.
   무료 건은 통째로 빈 문자열이라 :empty 로 여백까지 지운다. */
.preview-ovl-pay { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--pv-line, #e5e7eb); }
.preview-ovl-pay:empty { display: none; }
.preview-ovl-pay-head {
  margin: 0 0 8px; font-size: 12px; font-weight: 700;
  color: var(--pv-muted, #6b7280); letter-spacing: .02em;
}
/* 카드번호·가맹점번호는 자릿수를 눈으로 세는 값이라 고정폭으로 둔다. */
.preview-ovl-pay-list dd { font-variant-numeric: tabular-nums; }
.preview-ovl-pay-empty { font-size: 12px; color: var(--pv-muted, #9ca3af); }
/* 사진·링크 — 비어 있으면 margin 도 남기지 않는다(:empty). */
.preview-ovl-media { margin: 0 0 12px; }
.preview-ovl-media:empty { display: none; }
/* 높이를 고정한다. 프레임마다 비율이 제각각이라(가로 띠부터 2x6 세로 띠까지)
   원본 비율대로 두면 세로 띠 한 장이 오버레이를 화면 밖까지 밀어낸다.
   contain 이라 잘리지 않는다 — 확인용이니 전체가 보이는 쪽이 맞다. */
.preview-ovl-thumb {
  display: block; height: 168px; border-radius: 8px;
  overflow: hidden; background: var(--pv-bg);
}
.preview-ovl-thumb img {
  display: block; width: 100%; height: 100%; object-fit: contain;
  opacity: 1; transition: opacity .18s ease;
}
/* 사진이 오기 전에는 자리만 잡아 둔다. 도착하는 순간 나타나게 하면 아래
   내용이 밀리지 않는다 — 밀리면 누르려던 버튼이 손가락 밑에서 움직인다. */
.preview-ovl-thumb.is-loading img { opacity: 0; }
.preview-ovl-skel,
.preview-ovl-thumb.is-loading {
  background: linear-gradient(100deg,
    var(--pv-bg) 30%, rgba(255, 255, 255, .75) 50%, var(--pv-bg) 70%);
  background-size: 220% 100%;
  animation: preview-ovl-shimmer 1.1s linear infinite;
}
.preview-ovl-skel { display: block; height: 168px; border-radius: 8px; }
@keyframes preview-ovl-shimmer {
  from { background-position: 180% 0; }
  to { background-position: -80% 0; }
}
/* 움직임을 끈 사용자에게는 흐르지 않는 회색 자리만 남긴다. */
@media (prefers-reduced-motion: reduce) {
  .preview-ovl-skel,
  .preview-ovl-thumb.is-loading { animation: none; background: var(--pv-bg); }
}

/* 사진이 없을 때 — 이미지 자리를 통째로 비우지 않고 한 줄로 대신한다.
   빈 자리는 "못 불러왔다"로 읽히고, 한 줄은 "아직 없다"로 읽힌다. */
/* 사진 칸과 **같은 높이**를 쓴다. 로딩 자리가 168px 였다가 안내 문구에서
   갑자기 줄면 그 순간 아래가 통째로 올라붙어 눈에 거슬린다 — 자리를 미리
   잡아 둔 이유가 사라진다. */
.preview-ovl-nophoto {
  margin: 0; height: 168px; padding: 12px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; text-align: center;
  background: var(--pv-bg); color: var(--pv-text-mute);
  font-size: 13px; line-height: 1.4;
}
.preview-ovl-nophoto.is-pending {
  background: #fefce8; color: #a16207; font-weight: 600;
}
.preview-ovl-link {
  display: block; margin-top: 8px; padding: 9px; text-align: center;
  border: 1px solid var(--pv-border); border-radius: 8px; background: #fff;
  color: var(--pv-text); font-size: 13px; font-weight: 600; text-decoration: none;
}
/* 주소를 아직(혹은 영영) 모를 때. 자리는 지키고 누를 수 없게만 한다 —
   버튼이 나중에 생겨나면 그만큼 아래가 튄다. */
.preview-ovl-link.is-disabled {
  background: var(--pv-bg); color: var(--pv-text-mute);
  cursor: default; pointer-events: none; opacity: .6;
}
.preview-ovl-actions { margin-top: 16px; text-align: center; }
.preview-ovl-cancel {
  width: 100%; padding: 10px; border: 1px solid #fca5a5; border-radius: 8px;
  background: #fff; color: #b91c1c; font-size: 14px; font-weight: 600; cursor: pointer;
}
.preview-ovl-cancel:hover { background: #fef2f2; }
.preview-ovl-cancel:disabled { opacity: .5; cursor: default; }
.preview-ovl-warn {
  margin: 8px 0 0; font-size: 11px; line-height: 1.5; color: var(--pv-muted, #6b7280);
}
.preview-ovl-note { font-size: 13px; color: var(--pv-muted, #6b7280); }
.preview-ovl-release { display: block; margin-top: 8px; }
.preview-txn-time { font-variant-numeric: tabular-nums; color: var(--pv-text-soft); }
.preview-txn-booth { color: var(--pv-text-mute); }
.preview-txn-frame { color: var(--pv-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview-txn-method { font-size: 11px; color: var(--pv-text-soft); padding: 2px 6px; border: 1px solid var(--pv-border); border-radius: 999px; }
.preview-txn-amt { font-variant-numeric: tabular-nums; font-weight: 700; min-width: 70px; text-align: right; }
.preview-txn-more { display: block; width: 100%; margin-top: 10px; }
@media (max-width: 520px) {
  /* 모바일에서도 결제수단은 유지(컬럼 제거 금지), 부스만 숨김.
     세로점 칸을 빼먹으면 그것이 다음 줄로 떨어져 행이 두 겹이 된다. */
  .preview-txn-row {
    /* 초를 감추므로 "08-27 15:47" 11자면 된다. 남는 폭은 프레임 칸에 준다. */
    grid-template-columns: 68px minmax(0, 1fr) auto auto 18px;
    gap: 5px; font-size: 12px; padding: 8px 6px;
  }
  .preview-txn-booth { display: none; }
  .preview-txn-frame { min-width: 0; }
  /* 좁은 폭에서 "08-28 12:34:55" 는 한 줄에 안 들어간다. 초를 버린다 —
     같은 초에 두 건이 겹치는 일은 없고, 접히는 것보다 낫다. */
  .preview-txn-time { font-size: 11px; letter-spacing: -0.2px; }
  /* 좁은 폭에서는 더 줄인다. '중복결제 › 사진 전달' 이 최장 조합이다. */
  .preview-txn-row.has-action .preview-txn-frame,
  .preview-txn-row.is-photo-done .preview-txn-frame { font-size: 10px; }
  .preview-txn-time .sec { display: none; }
  .preview-txn-method { font-size: 10px; padding: 1px 5px; }
  .preview-txn-amt { min-width: 0; font-size: 12px; }
}

/* 모바일: 부스 카드 2열로(정확한 금액 수용) */
@media (max-width: 520px) {
  .preview-booth-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .preview-booth-revenue { font-size: 15px; }
  .preview-booth-card--all .preview-booth-revenue { font-size: 20px; }
}

/* ===== 하단 footer (안내 문구) ===== */
.preview-footer {
  margin-top: 28px;
  padding: 16px 4px 0;
  border-top: 1px solid var(--pv-border);
  color: var(--pv-text-mute);
  font-size: 12px;
  line-height: 1.6;
  text-align: center;
}

/* ── 사진 촬영중인 결제 ──────────────────────────────────────────────────
 * 결제 신호는 왔는데 사진이 오지 않은 건. 0건이면 통째로 숨는다(뷰에서 hidden).
 * 대부분의 날이 0건이라 자리를 늘 차지하면 눈에 안 들어오고, 그러면 정작 있을 때도
 * 안 보인다. 그래서 있을 때만 나타나고, 나타나면 눈에 띄어야 한다. */
.preview-pending {
  margin: 0 0 14px;
  border: 1px solid #f0c36d;
  background: #fff8e8;
  border-radius: 10px;
  overflow: hidden;
}

.preview-pending-head {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 11px 14px;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 14px;
  color: #7a5a12;
  text-align: left;
  cursor: pointer;
}

.preview-pending-head:hover {
  background: rgba(240, 195, 109, 0.14);
}

.preview-pending-mark {
  flex: none;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: #e0a52a;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  line-height: 19px;
  text-align: center;
}

.preview-pending-text { flex: 1 1 auto; }
.preview-pending-text b { font-weight: 700; }

.preview-pending-chev {
  flex: none;
  font-size: 11px;
  transition: transform 0.15s ease;
}

.preview-pending.is-open .preview-pending-chev { transform: rotate(180deg); }

.preview-pending-list {
  border-top: 1px solid #f0c36d;
  max-height: 260px;
  overflow-y: auto;
}

.preview-pending-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  font-size: 13px;
  color: #5c4a20;
  border-bottom: 1px solid rgba(240, 195, 109, 0.4);
}

.preview-pending-row:last-child { border-bottom: 0; }

/* "08-27 14:04" 11자면 된다. 넉넉히 잡으면 그만큼 기기 코드가 잘리는데,
   어느 기기인지가 원인 추적의 출발점이라 그쪽이 더 중요하다. */
.preview-pending-when { flex: none; width: 76px; font-variant-numeric: tabular-nums; }
.preview-pending-store { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 어느 기기인지가 원인 추적의 출발점이라 잘리지 않게 둔다. */
.preview-pending-dev { flex: none; color: #8a7440; font-size: 12px; }
.preview-pending-amt { flex: none; text-align: right; font-variant-numeric: tabular-nums; }

/* 건마다 고르는 체크. 라벨 전체가 눌리므로 작은 상자를 겨냥하지 않아도 된다. */
.preview-pending-row { cursor: pointer; }
.preview-pending-pick { flex: none; margin: 0; accent-color: #b45309; }

/* 펼친 목록 맨 아래의 일괄 조치. 목록과 색을 맞추되 경계는 분명히 둔다 —
   위는 "무엇이 남았나"이고 여기는 "무엇을 할까"라 성격이 다르다. */
.preview-pending-bulk {
  padding: 12px 14px 14px;
  border-top: 2px solid #f0c36d;
  background: #fffdf6;
}
.preview-pending-bulk-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px; font-size: 12px; color: #5c4a20;
}
.preview-pending-all { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.preview-pending-all input { margin: 0; accent-color: #b45309; }
.preview-pending-picked { font-weight: 700; }
.preview-pending-bulk .preview-ovl-action-label { color: #8a7440; }

.preview-pending-more {
  padding: 8px 14px;
  font-size: 12px;
  color: #8a7440;
  text-align: center;
}

@media (max-width: 560px) {
  .preview-pending-when { width: auto; }
  .preview-pending-dev { display: none; }
}

/* 용지 표 — 잔량은 막대와 숫자를 같이 둔다. 숫자만 있으면 500과 90의 차이가
   한눈에 안 들어오고, 막대만 있으면 정확한 값을 못 읽는다. */
.preview-paper-table td { vertical-align: middle; }
.preview-paper-level { white-space: nowrap; }
.preview-paper-bar {
  display: inline-block; width: 54px; height: 6px; margin-right: 6px;
  background: var(--pv-border); border-radius: 999px; overflow: hidden; vertical-align: middle;
}
.preview-paper-bar i { display: block; height: 100%; background: #0d9488; }
.preview-paper-num { font-variant-numeric: tabular-nums; }
.preview-paper-act { white-space: nowrap; }

/* ── 용지 종합 보고 (/preview/:brand/paper) ───────────────────────────────── */
.preview-header-sub { margin-left: 8px; font-size: 13px; color: var(--pv-text-soft); font-weight: 500; }
.preview-paper-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin-bottom: 10px;
}
.preview-paper-filters { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.preview-paper-sort {
  padding: 4px 10px; border: 1px solid var(--pv-border); border-radius: 999px;
  background: var(--pv-surface); color: var(--pv-text-soft); font-size: 12px; cursor: pointer;
}
.preview-paper-sort.is-on { background: var(--pv-text); color: var(--pv-surface); border-color: var(--pv-text); }
.preview-paper-check { display: inline-flex; align-items: center; gap: 4px; color: var(--pv-text-soft); cursor: pointer; }

/* 지점 한 덩이 — 사람은 기기가 아니라 지점 단위로 움직인다. */
.preview-paper-store {
  margin-bottom: 14px; padding: 10px 12px; background: var(--pv-surface);
  border: 1px solid var(--pv-border); border-radius: var(--pv-radius-sm);
}
.preview-paper-store.is-issue { border-color: #fca5a5; background: #fffafa; }
.preview-paper-store-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.preview-paper-store-name { font-size: 14px; font-weight: 700; }
.preview-paper-store-code { font-size: 11px; color: var(--pv-text-mute); font-family: ui-monospace, Menlo, monospace; }
.preview-paper-store-sum { margin-left: auto; font-size: 11px; color: var(--pv-text-soft); }

.preview-paper-table td b { font-weight: 700; }
.preview-paper-table .is-ok { color: var(--pv-text); }
.preview-paper-table .is-warn { color: #b45309; }
.preview-paper-table .is-fault { color: #b91c1c; }
.preview-paper-dev { text-align: left !important; }
.preview-paper-link {
  padding: 0; border: 0; background: none; cursor: pointer; text-decoration: underline dotted;
  font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--pv-text);
}
.preview-paper-warn { display: block; font-size: 10px; color: #b91c1c; }
.preview-paper-bar i.is-warn { background: #d97706; }
.preview-paper-bar i.is-fault { background: #b91c1c; }
.preview-paper-hist td { background: var(--pv-bg, #fafafa); text-align: left; }
.preview-paper-hist-box { display: flex; gap: 20px; flex-wrap: wrap; padding: 6px 2px; }
.preview-paper-hist-box > div { flex: 1 1 320px; min-width: 0; }
.preview-paper-hist-box h4 { margin: 0 0 6px; font-size: 12px; color: var(--pv-text-soft); }
.preview-total-v.is-warn { color: #b45309; }
.preview-total-v.is-fault { color: #b91c1c; }

@media (max-width: 560px) {
  .preview-paper-store-sum { margin-left: 0; }
  .preview-paper-hist-box { gap: 10px; }
}

/* ── 용지 보고 — 모바일 ─────────────────────────────────────────────────────
   표를 가로로 밀어 보게 하면 한 기기의 값을 끝까지 따라가지 못한다(2026-09-21 잘림 제보).
   좁은 화면에서는 기기 하나를 카드 한 장으로 편다: 칸 이름을 값 위에 작게 달고 두 줄로 놓는다. */
@media (max-width: 640px) {
  .preview-header-inner { flex-wrap: wrap; gap: 6px; }
  .preview-header-actions { flex-wrap: wrap; gap: 6px; }
  .preview-total-grid { grid-template-columns: repeat(2, 1fr); }
  .preview-total-cell { padding: 10px 12px; }

  .preview-paper-store { padding: 10px; }
  .preview-paper-store .preview-dev-scroll { overflow: visible; }
  .preview-paper-table, .preview-paper-table tbody,
  .preview-paper-mini, .preview-paper-mini tbody { display: block; width: 100%; border: 0; }
  .preview-paper-table thead, .preview-paper-mini thead { display: none; }

  .preview-paper-row {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px;
    padding: 12px 0; border-bottom: 1px solid var(--pv-border);
  }
  .preview-paper-row:last-of-type { border-bottom: 0; }
  .preview-paper-row td {
    display: block; padding: 0; border: 0; text-align: left; white-space: normal; font-size: 13px;
  }
  .preview-paper-row td[data-label]::before {
    content: attr(data-label); display: block; margin-bottom: 2px;
    font-size: 10px; color: var(--pv-text-soft); font-weight: 400;
  }
  .preview-paper-dev, .preview-paper-act { grid-column: 1 / -1; }
  .preview-paper-link { font-size: 13px; }
  .preview-paper-bar { width: 70px; }

  .preview-paper-hist:not([hidden]) { display: block; }
  .preview-paper-hist td { display: block; padding: 8px 0; }
  .preview-paper-mini tr {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px 10px;
    padding: 8px 0; border-bottom: 1px dashed var(--pv-border);
  }
  .preview-paper-mini td { display: block; padding: 0; border: 0; text-align: left; font-size: 12px; }
  .preview-paper-mini td[data-label]::before {
    content: attr(data-label); display: block; font-size: 10px; color: var(--pv-text-soft);
  }
  .preview-paper-filters { width: 100%; flex-wrap: wrap; }
}

/* 상단 접근 메뉴 — 헤더 바로 아래 한 줄. 좁은 화면에서는 가로로 밀어 본다. */
.preview-subnav {
  display: flex; gap: 6px; overflow-x: auto; -webkit-overflow-scrolling: touch;
  max-width: 1200px; margin: 0 auto; padding: 14px 20px 0;
  scrollbar-width: none;
}
.preview-subnav::-webkit-scrollbar { display: none; }
.preview-subnav-item {
  flex: 0 0 auto; padding: 5px 12px; border-radius: 999px; font-size: 12px; font-weight: 500;
  color: var(--pv-text-soft); background: var(--pv-surface); border: 1px solid var(--pv-border);
  text-decoration: none; white-space: nowrap;
}
.preview-subnav-item:hover { color: var(--pv-text); }
.preview-subnav-item.is-on { color: var(--pv-surface); background: var(--pv-text); border-color: var(--pv-text); }

/* ── 톤 맞춤(2026-09-21) — 용지 화면이 다른 화면과 따로 놀았다 ──────────────
   메뉴가 본문보다 4px 안쪽에서 시작했고, 표 글자·버튼이 다른 화면보다 한 단계 작았다. */
.preview-subnav + .preview-main { padding-top: 16px; }
.preview-subnav-item, .preview-paper-sort { padding: 6px 14px; font-size: 13px; }
.preview-paper-table { font-size: 13px; }
.preview-paper-table th { font-size: 12px; }
.preview-paper-link { text-decoration: none; text-align: left; font-family: inherit; }
.preview-paper-link:hover .preview-paper-devname { text-decoration: underline; }
.preview-paper-devname { display: block; font-size: 13px; font-weight: 600; color: var(--pv-text); }
.preview-paper-devcode {
  display: block; margin-top: 1px; font-size: 11px; color: var(--pv-text-mute);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.preview-paper-store-name { font-size: 15px; }
.preview-paper-store-sum { font-size: 12px; }
@media (max-width: 640px) {
  .preview-subnav { padding: 10px 16px 0; }
}

/* 조작 칸 — 이력(왼쪽)·재고(오른쪽) 두 개. 넓은 화면에서는 칸 오른쪽에 붙이고,
   좁은 화면에서는 반반으로 나눠 손가락으로 누르기 좋게 한다. */
.preview-paper-act { text-align: right; white-space: nowrap; }
@media (max-width: 640px) {
}

/* ── 버튼 체계 ────────────────────────────────────────────────────────────────
   기본 .preview-btn(외곽선) 하나에 크기와 성격만 덧붙인다. 화면마다 따로 만들었더니
   같은 「재고」 버튼이 화면마다 크기·여백이 달랐다(2026-09-21).
     크기   --sm        표 안 조작
     성격   (기본)      외곽선 — 보기·이동(이력 등)
            --solid     진한 채움 — 값을 바꾸는 조작(재고 입력 등)
            --primary   강조색 — 화면의 주 행동(로그인·적용)
            --ghost     배경 없음 — 머리글 보조(새로고침·로그아웃) */
.preview-btn--sm { padding: 6px 12px; font-size: 12px; line-height: 1.2; border-radius: 8px; }
.preview-btn--solid { background: var(--pv-text); border-color: var(--pv-text); color: var(--pv-surface); }
.preview-btn--solid:hover { background: #2b2b2b; border-color: #2b2b2b; }
.preview-paper-act .preview-btn + .preview-btn { margin-left: 6px; }
@media (max-width: 640px) {
  /* 카드 칸 규칙(.preview-paper-row td { display:block })보다 구체적이어야 이긴다. */
  .preview-paper-row td.preview-paper-act { display: flex; gap: 8px; }
  .preview-paper-row td.preview-paper-act .preview-btn { flex: 1 1 0; margin: 0; padding: 11px 12px; font-size: 14px; }
}

/* ── 이력 창(용지) ───────────────────────────────────────────────────────────
   넓은 창 하나. 좁은 화면에서는 아래에서 올라오는 전체 폭 시트로 편다. */
body.is-modal-open { overflow: hidden; }
.preview-modal { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; }
.preview-modal[hidden] { display: none; }
.preview-modal-backdrop { position: absolute; inset: 0; background: rgba(15, 17, 21, .45); }
.preview-modal-box {
  position: relative; display: flex; flex-direction: column;
  width: min(760px, 92vw); max-height: 86vh;
  background: var(--pv-surface); border-radius: 14px; box-shadow: 0 20px 60px rgba(0, 0, 0, .25);
}
.preview-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 18px 20px 10px;
}
.preview-modal-title { margin: 0; font-size: 17px; font-weight: 700; }
.preview-modal-sub { margin: 4px 0 0; font-size: 12px; color: var(--pv-text-soft); }
.preview-modal-tabs { display: flex; gap: 4px; padding: 0 20px; border-bottom: 1px solid var(--pv-border); }
.preview-modal-tab {
  padding: 9px 14px; border: 0; background: none; font-size: 14px; font-weight: 500;
  color: var(--pv-text-soft); border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer;
}
.preview-modal-tab.is-on { color: var(--pv-text); border-bottom-color: var(--pv-text); font-weight: 700; }
.preview-modal-body { flex: 1 1 auto; overflow-y: auto; padding: 8px 20px; }
.preview-modal-foot { padding: 10px 20px 18px; text-align: center; }
.preview-modal-foot .preview-btn { min-width: 160px; }

.preview-hist-list { list-style: none; margin: 0; padding: 0; }
.preview-hist-item { padding: 12px 0; border-bottom: 1px solid var(--pv-border); }
.preview-hist-item:last-child { border-bottom: 0; }
.preview-hist-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; }
.preview-hist-main { margin-top: 4px; font-size: 14px; font-variant-numeric: tabular-nums; }
.preview-hist-soft { margin-top: 2px; font-size: 12px; color: var(--pv-text-soft); }
.preview-hist-tag {
  flex: 0 0 auto; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 600;
  background: #f1f3f5; color: var(--pv-text-soft);
}
.preview-hist-tag.is-up { background: #dcfce7; color: #166534; }
.preview-hist-tag.is-down { background: #fee2e2; color: #991b1b; }
.preview-hist-empty { padding: 28px 0; text-align: center; font-size: 13px; color: var(--pv-text-soft); }

@media (max-width: 640px) {
  .preview-modal { align-items: flex-end; }
  .preview-modal-box { width: 100vw; max-height: 88vh; border-radius: 16px 16px 0 0; }
  .preview-modal-head, .preview-modal-body, .preview-modal-foot { padding-left: 16px; padding-right: 16px; }
  .preview-modal-tabs { padding: 0 16px; }
  .preview-modal-foot .preview-btn { width: 100%; }
}

/* 프린트 잔량 카드 — 기기 수만큼 나눈다(열 수는 grid.js 가 정한다). 용지 관리 브랜드는
   기기 이름·재고·「관리」를 카드 안에 둔다 — 지점 화면에서 따로 표를 펼칠 필요가 없게. */
.preview-kiosks-strip .preview-kiosk-chip {
  display: flex; flex-direction: column; gap: 6px; min-width: 0;
  padding: 12px 14px; border-radius: var(--pv-radius); text-align: left;
}
.preview-kiosk-chip-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; min-width: 0; }
/* 번호는 위 줄, 이름은 아래 줄에 다 보이게(말줄임 없이) */
.preview-kiosks-strip .preview-kiosk-chip-id {
  margin: 0; min-width: 0; font-family: inherit; font-size: 14px; font-weight: 700; color: var(--pv-text);
  line-height: 1.3; word-break: keep-all;
}
.preview-kiosk-chip-id .preview-booth-code { display: block; margin: 0 0 1px; }
.preview-kiosk-chip-body { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.preview-kiosks-strip .preview-kiosk-chip-remain { font-size: 22px; font-weight: 800; letter-spacing: -0.01em; }
.preview-kiosk-chip-remain small { margin-left: 2px; font-size: 12px; font-weight: 500; color: var(--pv-text-soft); }
.preview-kiosk-chip-stock { font-size: 12px; color: var(--pv-text-soft); white-space: nowrap; }
.preview-kiosk-chip-stock b { color: var(--pv-text); }
.preview-kiosk-chip-bar { margin-top: 2px; }
.preview-kiosk-chip--low .preview-kiosk-chip-bar i { background: var(--pv-danger); }
/* 「관리」— 카드 머리 오른쪽의 작은 글자 버튼 */
.preview-kiosk-manage {
  flex: none; padding: 3px 9px; border: 1px solid var(--pv-border); border-radius: 999px;
  background: var(--pv-surface); color: var(--pv-text-soft); font: inherit; font-size: 11px; font-weight: 600; cursor: pointer;
}
.preview-kiosk-manage:hover { color: var(--pv-text); border-color: #c9c9d1; }

/* 관리 창 다듬기(2026-09-21) — 좁은 폭에서 머리 버튼 둘이 세로로 쌓이고, 탭에 클릭 포커스
   테두리가 남고, 한 건이 세 줄을 먹었다. 닫기는 ✕ 하나로, 손이 가는 버튼은 아래로 내린다. */
.preview-modal-headtext { min-width: 0; flex: 1 1 auto; }
.preview-modal-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.preview-modal-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.preview-modal-close {
  flex: 0 0 auto; width: 34px; height: 34px; margin: -4px -6px 0 0;
  border: 0; border-radius: 8px; background: none; font-size: 18px; line-height: 1;
  color: var(--pv-text-soft); cursor: pointer;
}
.preview-modal-close:hover { background: var(--pv-bg, #f4f5f7); color: var(--pv-text); }
.preview-modal-tab:focus { outline: none; }
.preview-modal-tab:focus-visible { outline: 2px solid var(--pv-accent); outline-offset: -2px; border-radius: 6px; }
.preview-modal-foot { display: flex; gap: 8px; }
.preview-modal-foot .preview-btn { flex: 1 1 0; min-width: 0; padding: 11px 12px; font-size: 14px; }

.preview-hist-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 0; }
.preview-hist-left { min-width: 0; }
.preview-hist-date { font-size: 12px; color: var(--pv-text-soft); font-variant-numeric: tabular-nums; }
.preview-hist-item .preview-hist-main { margin-top: 2px; font-size: 14px; font-weight: 600; }

/* 프린트 잔량 자리 잡기 — 불러오는 동안 카드 한 장 크기의 회색 틀을 둔다. */
.preview-kiosk-skel {
  grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; min-height: 64px; padding: 10px; border: 1px solid var(--pv-border);
  border-radius: var(--pv-radius-sm); background: var(--pv-surface);
}
.preview-kiosk-skel.is-tall { min-height: 96px; }
.preview-kiosk-skel i {
  display: block; height: 10px; width: 40%; border-radius: 6px;
  background: linear-gradient(90deg, #eef0f3 0%, #f7f8fa 50%, #eef0f3 100%);
  background-size: 200% 100%; animation: pv-skel 1.2s ease-in-out infinite;
}
.preview-kiosk-skel i:nth-child(2) { width: 25%; height: 16px; }
.preview-kiosk-skel i:nth-child(3) { width: 55%; }
@keyframes pv-skel { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }

/* 재고 변동 태그 — 누가 바꿨나. 자동(교체 감지)은 파랑, 사용자 입력은 호박, PB24 이관은 회색. */
.preview-hist-tag.is-auto { background: #dbeafe; color: #1e40af; }
.preview-hist-tag.is-manual { background: #fef3c7; color: #92400e; }
.preview-hist-tag.is-suspect { background: #fee2e2; color: #b91c1c; }
.preview-hist-tag.is-pb24 { background: #f1f3f5; color: var(--pv-text-soft); }

/* 태그 두 줄 — 위: 자동 차감(파랑)/사용자 입력(호박), 아래: 무엇이 얼마나(중립). */
.preview-hist-tags { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: 0 0 auto; }

/* 내수 / 글로벌 타일 — 글로벌 안 통화가 둘 이상이면 통화마다 한 줄(위안 · CNY) */
.preview-market-cur { margin-top: 8px; font-size: 11px; font-weight: 600; color: var(--pv-text-soft); }

/* 나라별 매출 — 통화가 둘 이상일 때 나라마다 한 덩어리(2026-09-28, views/_preview/_country_rows.ejs).
   국기·나라 이름 아래에 이번달·오늘 두 칸을 같은 크기로 — 오늘이 작은 글자로 밀려 안 보였다.
   칸 너비를 글자 크기(em) 기준으로 잡아, 휴대폰 글꼴을 키우면 두 칸이 위아래로 쌓인다(어르신 화면). */
.pv-cty { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; min-width: 0; }
.pv-cty-row { min-width: 0; }
.pv-cty-row + .pv-cty-row { padding-top: 10px; border-top: 1px solid var(--pv-border); }
.pv-cty-name { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; font-size: 14px; font-weight: 700; color: var(--pv-text); }
.pv-cty-figs { display: grid; grid-template-columns: repeat(auto-fit, minmax(9em, 1fr)); gap: 6px; }
.pv-cty-fig {
  display: grid; grid-template-columns: auto 1fr; grid-template-areas: "k n" "v v";
  align-items: baseline; column-gap: 6px; padding: 7px 10px; border-radius: 8px; background: #f3f6fb; min-width: 0;
}
.pv-cty-fig.is-today { background: #f4f7f4; }
.pv-cty-k { grid-area: k; font-size: 12px; font-weight: 600; color: var(--pv-text-soft); }
.pv-cty-n { grid-area: n; text-align: right; font-size: 12px; color: var(--pv-text-soft); font-variant-numeric: tabular-nums; }
.pv-cty-fig b { grid-area: v; font-size: clamp(14px, 4.2vw, 17px); font-weight: 800; color: var(--pv-text); font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -0.01em; }
.pv-cty-fig.is-zero b { color: var(--pv-text-mute); }
/* 금액은 끊지 않는다(₩656,220,00 / 0 으로 꺾였다) — 좁은 화면에서는 글자를 줄여 한 줄에 둔다. */
.pv-cty--big .pv-cty-fig b { font-size: clamp(15px, 4.6vw, 20px); }
.pv-cty--big .pv-cty-name { font-size: 15px; }
.preview-total-cell--cty { grid-column: 1 / -1; }

/* 카드 태그 — 이름 앞 브랜드색 동그라미(2026-09-28). 지점 카드는 동그라미 안에 지점 번호.
   왼쪽 46px 색 띠가 너무 커서 걷었다. 번호가 세 자리여도 알약으로 늘어난다. */
.pv-tag {
  display: inline-flex; align-items: center; justify-content: center; vertical-align: -1px;
  min-width: 24px; height: 24px; padding: 0 6px; margin-right: 8px; border-radius: 999px;
  background: var(--sw, var(--pv-text-mute)); color: #fff;
  font-size: 12px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .25);   /* 밝은 브랜드색 위에서도 번호가 읽히게 */
}
.pv-tag i { display: none; }
.pv-tag--dot { min-width: 14px; width: 14px; height: 14px; padding: 0; vertical-align: 0; }

/* 매출 칸 — 이번달·오늘을 은은한 바탕의 작은 칸 두 개로(2026-09-28, PB24 매니저 카드에서 가져옴).
   PB24 는 칸이 커서 카드 하나가 화면 절반을 먹었다. 라벨·건수 한 줄 + 금액 한 줄로 낮게 둔다. */
.preview-store-figs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 6px; }
.preview-store-fig {
  display: grid; grid-template-columns: auto 1fr; grid-template-areas: "k n" "v v";
  align-items: baseline; column-gap: 6px; row-gap: 1px; min-height: 0;
  padding: 6px 10px; border-radius: 8px; background: #f3f6fb;
}
.preview-store-fig--soft { background: #f4f7f4; }
.preview-store-fig .preview-store-fig-k { grid-area: k; }
.preview-store-fig .preview-store-fig-n { grid-area: n; text-align: right; }
.preview-store-fig .preview-store-fig-v { grid-area: v; font-size: 15px; font-weight: 700; color: var(--pv-text); white-space: nowrap; }
.preview-store-fig--soft .preview-store-fig-v { font-size: 15px; font-weight: 700; color: var(--pv-text); }
.preview-store-fig.is-zero .preview-store-fig-v { color: var(--pv-text-mute); }
@media (max-width: 560px) { .preview-store-figs { gap: 6px; } }

/* 지점 목록 위 요약판 — 운영 지점·이번달·오늘(평소 이 시각 대비)·하루 평균·동시간 평균. */
.pv-sum { margin-bottom: 14px; }
.pv-sum-title { margin: 0 0 6px; font-size: 12px; font-weight: 700; color: var(--pv-text-soft); }
.pv-sum-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 640px) { .pv-sum-grid { grid-template-columns: 1fr 1fr; gap: 6px; } }
.pv-sum-cell {
  display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; min-width: 0;
  background: var(--pv-surface); border: 1px solid var(--pv-border); border-radius: var(--pv-radius);
}
.pv-sum-cell.is-month { background: #f3f6fb; border-color: #e3e9f3; }
.pv-sum-cell.is-today { background: #f4f7f4; border-color: #e2ebe3; }
.pv-sum-k { font-size: 11px; font-weight: 600; color: var(--pv-text-soft); }
.pv-sum-cell b { font-size: 17px; font-weight: 800; color: var(--pv-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pv-sum-cell b small { margin-left: 2px; font-size: 12px; font-weight: 600; color: var(--pv-text-soft); }
.pv-sum-cell > small { font-size: 11px; color: var(--pv-text-mute); }
.pv-sum-cell .is-up { color: #15803d; font-weight: 700; }
.pv-sum-cell .is-down { color: #b45309; font-weight: 700; }

/* 바로가기 링크 발급 결과 — 한 번만 보인다. */
.pv-newlink input { display: block; width: 100%; margin: 8px 0 4px; padding: 8px 10px; font: 13px ui-monospace, monospace;
  border: 1px solid var(--pv-border); border-radius: 6px; background: #fff; }
.pv-newlink small { color: var(--pv-text-soft); }

/* 첫 화면 날짜 선택 — 일별(날짜 칸을 누르면 달력) · 월별 · 기간 */
.pv-period { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 0 0 12px; }
.pv-period-modes { display: inline-flex; padding: 3px; gap: 2px; background: var(--pv-bg); border: 1px solid var(--pv-border); border-radius: 999px; }
.pv-period-mode { border: 0; background: none; padding: 7px 14px; border-radius: 999px; font: inherit; font-size: 14px; font-weight: 600; color: var(--pv-text-soft); cursor: pointer; }
.pv-period-mode.is-on { background: var(--pv-text); color: #fff; }
.pv-period-inputs { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pv-period-inputs input { font: inherit; font-size: 15px; font-weight: 600; padding: 7px 10px; border: 1px solid var(--pv-border); border-radius: 8px; background: var(--pv-surface); color: var(--pv-text); min-height: 40px; }
.pv-period-today { font-size: 13px; font-weight: 600; color: var(--pv-accent); text-decoration: none; }
/* 총합의 기기 칸 — 옆이 비어 회색으로 남던 것(자리 수가 안 맞아서)을 한 줄 전체로 */
.preview-total-grid > .preview-total-cell:not(.preview-total-cell--cty) { grid-column: 1 / -1; }

/* 목록 화면(브랜드·내수/글로벌·지점)은 휴대폰 기준으로 만든 화면이라 넓은 화면에서 끝없이 늘어나지 않게
   가운데 1024px 로 묶는다(2026-09-28). */
.pv-narrow .preview-main,
.pv-narrow .preview-header-inner,
.pv-narrow .preview-subnav { max-width: 1024px; margin-left: auto; margin-right: auto; }

/* 카드 아래 「자세히 보기」(2026-09-28) — 오른쪽 큰 화살표(28px)가 카드 폭을 먹어 숫자 칸을 좁혔다.
   카드를 세로로 쌓고, 맨 아래 옅은 선으로 갈라 한 줄로 둔다. 카드 전체가 눌리는 것은 그대로다. */
.preview-brand-card--bar { flex-direction: column; align-items: stretch; gap: 0; }
.preview-brand-card--bar .preview-brand-meta { padding: 14px 0 10px; }
.preview-brand-card--bar .preview-brand-cta {
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
  margin: 0; padding: 9px 0 11px; border-top: 1px dashed var(--pv-border);
  font-size: 13px; font-weight: 600; color: var(--pv-text-soft); line-height: 1.2;
}
.preview-brand-card--bar .preview-brand-cta b { font-size: 17px; font-weight: 700; line-height: 1; }
.preview-brand-card--bar:hover .preview-brand-cta { color: var(--pv-accent); transform: none; }

/* 빈 자리 걷기(2026-09-28) — 상태 칩이 없는 카드의 빈 줄(30px)과 카드 최소 높이(116px)가 「자세히 보기」
   위에 큰 공백을 만들었다. 칩이 없으면 줄을 접고, 높이는 내용만큼. */
.preview-store-marks:not(:has(*)) { display: none; }
.preview-store-row { min-height: 0; }
/* 매출 두 칸도 글자 크기(em) 기준 — 휴대폰 글꼴을 키우면 위아래로 쌓인다. */
.preview-store-figs { grid-template-columns: repeat(auto-fit, minmax(9em, 1fr)); }
.pv-sum-grid { grid-template-columns: repeat(auto-fit, minmax(9em, 1fr)); }
@media (max-width: 640px) { .pv-sum-grid { grid-template-columns: repeat(auto-fit, minmax(9em, 1fr)); } }

/* 자간·행간(2026-09-28) — 칸 안 라벨·건수와 금액이 붙어 답답했다. 줄 사이를 띄우고 라벨은 살짝 벌린다.
   금액은 좁히지 않는다(숫자끼리 붙으면 자릿수를 잘못 읽는다). */
.pv-cty { gap: 12px; }
.pv-cty-row + .pv-cty-row { padding-top: 12px; }
.pv-cty-name { margin-bottom: 8px; gap: 7px; line-height: 1.3; letter-spacing: .01em; }
.pv-cty-figs, .preview-store-figs { gap: 8px; }
.pv-cty-fig, .preview-store-fig { padding: 9px 12px 10px; row-gap: 5px; }
.pv-cty-k, .pv-cty-n,
.preview-store-fig .preview-store-fig-k, .preview-store-fig .preview-store-fig-n { font-size: 12px; line-height: 1.3; letter-spacing: .02em; }
.pv-cty-fig b, .preview-store-fig .preview-store-fig-v { line-height: 1.25; letter-spacing: .005em; }
.preview-brand-card--bar .preview-brand-name { line-height: 1.35; letter-spacing: .005em; }
.preview-brand-card--bar .preview-brand-code { margin-top: 3px; letter-spacing: .02em; }
.preview-brand-card--bar .preview-brand-meta { padding: 16px 0 12px; }
.preview-brand-card--bar .preview-brand-cta { padding: 10px 0 12px; letter-spacing: .02em; }

/* 「전체」 화면 사진 카드 — 찍은 지점 이름(부스 번호만으로는 지점을 몰랐다) */
.preview-card-store { font-size: 14px; font-weight: 700; color: var(--pv-text); line-height: 1.35;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 요약판 다시 짜기(2026-09-28) — PB24 매니저 화면(photobox.airout.kr/manager)을 따른다:
   가운데 정렬한 파란 라벨, 그 아래 큰 숫자, 은은한 바탕 타일. PB24 타일은 너무 높았으므로 여백은 줄인다.
   어르신이 휴대폰 글꼴을 키워도 깨지지 않게 칸 폭은 글자 크기(em) 기준 — 좁으면 위아래로 쌓인다. */
.pv-sum {
  margin: 0 0 16px; padding: 14px 14px 0; background: var(--pv-surface);
  border: 1px solid var(--pv-border); border-radius: 14px;
}
.pv-sum-title { display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  margin: 0 2px 12px; font-size: 17px; font-weight: 800; color: var(--pv-text); line-height: 1.3; letter-spacing: -.005em; }
.pv-sum-title span { font-size: 14px; font-weight: 600; color: var(--pv-text-soft); white-space: nowrap; }
.pv-sum-grid, .pv-sum-avg-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5em, 1fr)); gap: 8px; }
.pv-sum-cell, .pv-sum-avg-grid > div {
  display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0;
  padding: 12px 8px 11px; text-align: center; border: 0; border-radius: 12px;
}
.pv-sum-cell { background: #eef3fb; }
.pv-sum-cell.is-month { background: #eef3fb; border: 0; }
.pv-sum-cell.is-today { background: #edf6f0; border: 0; }
.pv-sum-k, .pv-sum-avg-grid span { font-size: 14px; font-weight: 700; color: #2563eb; letter-spacing: .02em; line-height: 1.3; }
.pv-sum-cell.is-today .pv-sum-k { color: #15803d; }
.pv-sum-cell b { font-size: clamp(21px, 6.2vw, 26px); font-weight: 800; line-height: 1.2; letter-spacing: 0;
  color: var(--pv-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pv-sum-cell > small, .pv-sum-avg-grid small { font-size: 13px; color: var(--pv-text-soft); line-height: 1.3; letter-spacing: .01em; }
/* 평균 — 평소 이 시각·하루 평균 두 칸. 매출 두 칸보다 작게(시선은 매출에). */
.pv-sum-avg { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--pv-border); }
.pv-sum-avg-k { margin-bottom: 6px; text-align: center; font-size: 14px; font-weight: 700; color: #2563eb; letter-spacing: .02em; }
.pv-sum-avg-grid > div { background: var(--pv-bg); padding: 10px 8px 9px; }
.pv-sum-avg-grid span { font-size: 13px; color: var(--pv-text-soft); }
.pv-sum-avg-grid b { font-size: 18px; font-weight: 800; line-height: 1.2; color: var(--pv-text);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.pv-sum-avg-grid small { font-size: 12px; }
/* 판 아래 — 이 범위 전체 매출로. 카드 「자세히 보기」와 같은 점선 한 줄. */
.pv-sum-more { display: flex; align-items: center; justify-content: flex-end; gap: 4px;
  margin: 12px -14px 0; padding: 12px 14px 13px; border-top: 1px dashed var(--pv-border);
  font-size: 14px; font-weight: 600; color: var(--pv-text-soft); text-decoration: none; letter-spacing: .02em; }
.pv-sum-more b { font-size: 18px; line-height: 1; }
.pv-sum-more:hover { color: var(--pv-accent); }

/* 매출 타일 한 규칙(2026-09-28) — 요약판·지점 카드·브랜드 카드·나라별 칸이 모두 같은 모양이다.
   이번달 = 파란 라벨 + 옅은 파랑 바탕, 오늘 = 초록 라벨 + 옅은 초록 바탕.
   라벨·금액·건수는 가운데 정렬로 위에서 아래로 놓는다. 오늘 칸을 흐리게 하지 않는다.
   금액 크기는 칸 폭(cqi)에 맞춘다 — 억 단위 금액이 칸 밖으로 넘치던 것. */
.pv-sum-cell, .preview-store-fig, .pv-cty-fig {
  container-type: inline-size;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; min-width: 0; min-height: 0; padding: 11px 8px 10px;
  text-align: center; border: 0; border-radius: 12px; background: #eef3fb;
}
.pv-sum-cell.is-today, .preview-store-fig--soft, .pv-cty-fig.is-today { background: #edf6f0; }
.pv-sum-k, .preview-store-fig .preview-store-fig-k, .pv-cty-k {
  order: 0; font-size: 14px; font-weight: 700; line-height: 1.3; letter-spacing: .02em; color: #2563eb; text-align: center;
}
.pv-sum-cell.is-today .pv-sum-k, .preview-store-fig--soft .preview-store-fig-k, .pv-cty-fig.is-today .pv-cty-k { color: #15803d; }
.pv-sum-cell b, .preview-store-fig .preview-store-fig-v, .preview-store-fig--soft .preview-store-fig-v, .pv-cty-fig b {
  order: 1; display: block; max-width: 100%;
  font-size: clamp(15px, 12cqi, 24px); font-weight: 800; line-height: 1.2; letter-spacing: 0;
  color: var(--pv-text); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.pv-sum-cell b { font-size: clamp(16px, 12.5cqi, 28px); }
.pv-sum-cell > small, .preview-store-fig .preview-store-fig-n, .pv-cty-n {
  order: 2; font-size: 13px; font-weight: 500; line-height: 1.3; letter-spacing: .01em; color: var(--pv-text-soft); text-align: center;
}
.preview-store-fig.is-zero .preview-store-fig-v, .pv-cty-fig.is-zero b { color: var(--pv-text-mute); }
.preview-store-figs { display: grid; grid-template-columns: repeat(auto-fit, minmax(9em, 1fr)); gap: 8px; align-items: stretch; }
.pv-sum-avg { margin-top: 10px; padding-top: 10px; }
/* 통화 기호는 숫자보다 작게(2026-09-28) — 「S$0.00」처럼 기호가 숫자와 같은 크기면 기호가 두 번 찍힌 것처럼 읽혔다. */
.pv-cur { font-size: .68em; font-weight: 700; margin-right: .12em; color: var(--pv-text-soft); vertical-align: .08em; }

/* 지점 목록 도구줄(2026-09-28) — 정렬(번호·이번달·오늘 매출순, URL) · 보기(카드/목록, 이 기기에 기억).
   AOBSC 허브 목록을 참고했다. 날짜 선택과 같은 둥근 토글 모양. */
.pv-listbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 12px; }
.pv-seg { display: inline-flex; flex-wrap: wrap; padding: 3px; gap: 2px; background: var(--pv-bg); border: 1px solid var(--pv-border); border-radius: 999px; }
.pv-seg-btn { border: 0; background: none; padding: 7px 12px; border-radius: 999px; font: inherit; font-size: 14px; font-weight: 600;
  line-height: 1.2; color: var(--pv-text-soft); text-decoration: none; cursor: pointer; white-space: nowrap; }
.pv-seg-btn.is-on { background: var(--pv-text); color: #fff; }
/* 매출순일 때만 — 통화(나라) 묶음 안의 순위 */
.pv-rank { display: inline-block; min-width: 2.2em; margin-right: 6px; font-size: 13px; font-weight: 800; color: #2563eb;
  font-variant-numeric: tabular-nums; }
.pv-list-head { display: none; }

/* 목록 보기 — 한 줄: 순위·번호·지점명 | 이번달 | 오늘. 금액은 약칭 없이 전체.
   칸 폭은 목록 전체에서 가장 긴 금액에 맞춘다(subgrid) — 고정 폭이면 지점명이 「스…」로 잘렸다.
   글꼴을 키워 목록 폭이 24em 아래로 줄면 지점명 한 줄 + 금액 한 줄로 바꾼다(높이 고정 없음). */
.preview-store-list.is-list {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 0;
  background: var(--pv-surface); border: 1px solid var(--pv-border); border-radius: 14px; overflow: hidden;
}
.is-list .pv-list-head, .is-list .preview-store-row {
  display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; column-gap: 12px;
}
.is-list .pv-list-head {
  padding: 9px 12px 7px; border-bottom: 1px solid var(--pv-border); background: var(--pv-bg);
  font-size: 12px; font-weight: 700; color: var(--pv-text-soft); letter-spacing: .02em;
}
.is-list .pv-list-head .is-month { color: #2563eb; text-align: right; }
.is-list .pv-list-head .is-today { color: #15803d; text-align: right; }
.is-list .preview-store-row {
  margin: 0; padding: 11px 12px; min-height: 0; border: 0; border-bottom: 1px solid var(--pv-border);
  border-radius: 0; box-shadow: none; background: transparent;
}
.is-list .preview-store-row:last-child { border-bottom: 0; }
.is-list .preview-store-row:hover { background: var(--pv-bg); transform: none; }
.is-list .preview-store-row .preview-brand-meta,
.is-list .preview-store-row .preview-store-bottom,
.is-list .preview-store-row .preview-store-figs { display: contents; }
.is-list .preview-store-row .preview-brand-code,
.is-list .preview-store-row .preview-store-marks,
.is-list .preview-store-row .preview-brand-cta { display: none; }
.is-list .preview-store-row .preview-brand-name {
  display: flex; align-items: center; min-width: 0; margin: 0; font-size: 15px; font-weight: 700; line-height: 1.3;
}
.is-list .preview-store-row .pv-store-nm { min-width: 0; word-break: keep-all; overflow-wrap: anywhere; }  /* 잘라 「스티커즈 중…」으로 두지 않고 두 줄로 */
.is-list .preview-store-row .pv-tag { flex-shrink: 0; min-width: 22px; height: 22px; margin-right: 7px; font-size: 11px; }
.is-list .pv-rank { flex-shrink: 0; min-width: 1.4em; margin-right: 4px; }
.is-list .pv-rank small { display: none; }
/* 기기 고장이 있으면 이름 끝에 빨간 점 하나 — 상태 줄은 카드 보기에서 */
.is-list .preview-store-row:has(.preview-store-mark.is-fault) .preview-brand-name::after {
  content: ''; flex-shrink: 0; width: 8px; height: 8px; margin-left: 6px; border-radius: 50%; background: #dc2626;
}
.is-list .preview-store-row .preview-store-fig {
  container-type: normal; display: block; padding: 0; min-width: 0; background: none; border-radius: 0; text-align: right;
}
.is-list .preview-store-row .preview-store-fig-k,
.is-list .preview-store-row .preview-store-fig-n { display: none; }
.is-list .preview-store-row .preview-store-fig .preview-store-fig-v {
  display: inline; font-size: 15px; font-weight: 700; line-height: 1.3; white-space: nowrap;
}
.is-list .preview-store-row .preview-store-fig--soft .preview-store-fig-v { color: #166534; }
.is-list .preview-store-row .preview-store-fig.is-zero .preview-store-fig-v { color: var(--pv-text-mute); }
/* 목록 폭을 재는 틀은 목록을 담은 칸(목록 자신은 폭 규칙을 바꿔야 해서 틀이 될 수 없다) */
.preview-section:has(> #pv-store-list) { container-type: inline-size; }
@container (max-width: 20em) {
  /* 글꼴을 크게 쓴 휴대폰 — 지점명 한 줄(줄바꿈 허용), 그 아래 오른쪽에 이번달·오늘. 칸 머리 대신 칸마다 작은 라벨. */
  .is-list .pv-list-head { display: none; }
  .preview-store-list.is-list { display: block; }
  .is-list .preview-store-row { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: flex-end; gap: 4px 14px; }
  .is-list .preview-store-row .preview-brand-name { flex: 1 0 100%; }
  .is-list .preview-store-row .pv-store-nm { white-space: normal; }
  .is-list .preview-store-row .preview-store-fig-k { display: inline; margin-right: 5px; font-size: 12px; }
}
/* 목록 보기 글자 조정(2026-09-28) — 지점명은 한 줄(넘치면 …), 한 단계 작게. 눈이 먼저 가는 건 금액.
   순위·번호 원은 조금 작게, 칸 사이도 좁혀 지점명 자리를 넓힌다. */
.is-list .pv-list-head, .is-list .preview-store-row { column-gap: 8px; }
.is-list .preview-store-row { padding: 12px 12px; }
.is-list .preview-store-row .preview-brand-name { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.is-list .preview-store-row .pv-store-nm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; word-break: normal; overflow-wrap: normal; }
.is-list .pv-rank { min-width: 1.3em; margin-right: 2px; font-size: 13px; }
.is-list .preview-store-row .pv-tag { min-width: 20px; height: 20px; padding: 0 5px; margin-right: 6px; font-size: 11px; }
.is-list .preview-store-row .preview-store-fig .preview-store-fig-v { font-size: 15px; font-weight: 800; letter-spacing: -.005em; }
.is-list .preview-store-row .pv-cur { font-size: .64em; margin-right: .1em; }
@container (max-width: 20em) {
  .is-list .preview-store-row .pv-store-nm { white-space: normal; }
}
.is-list .preview-store-row { padding: 12px 10px; }
.is-list .pv-list-head { padding-left: 10px; padding-right: 10px; }
.is-list .preview-store-row .preview-store-fig .preview-store-fig-v { font-size: 14px; }
.is-list .preview-store-row .preview-brand-name { font-size: 14px; }
/* 목록에서 매출순일 때는 순위만 — 순위와 지점 번호 원이 나란히 서면 지점명이 다섯 글자로 줄었다. 번호순일 때는 번호 원. */
.is-list .preview-store-row .pv-rank + .pv-tag { display: none; }
.is-list .pv-rank { min-width: 1.6em; margin-right: 6px; font-size: 14px; }
/* 목록 화면 맨 아래 여유(2026-09-28) — 마지막 지점이 화면 끝에 붙어 엄지로 끌어올리기 불편했다. */
.pv-narrow .preview-main { padding-bottom: calc(120px + env(safe-area-inset-bottom, 0px)); }

/* 투출 실패 영상(2026-09-30) — 목록 한 줄: 시각 · 결과 · 기기·칸 · 승인번호. 재생 화면은 영상 + 정의 목록. */
.pv-inc-filter { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.pv-inc-filter input, .pv-inc-filter select { font: inherit; font-size: 15px; padding: 8px 10px; min-height: 40px;
  border: 1px solid var(--pv-border); border-radius: 8px; background: var(--pv-surface); color: var(--pv-text); flex: 1 1 9em; }
.pv-inc-list { background: var(--pv-surface); border: 1px solid var(--pv-border); border-radius: 14px; overflow: hidden; }
.pv-inc-row { display: grid; grid-template-columns: auto 1fr; gap: 3px 10px; padding: 12px; border-bottom: 1px solid var(--pv-border);
  color: var(--pv-text); text-decoration: none; font-size: 14px; line-height: 1.35; }
.pv-inc-row:last-child { border-bottom: 0; }
.pv-inc-row:hover { background: var(--pv-bg); }
.pv-inc-when { font-weight: 700; font-variant-numeric: tabular-nums; }
.pv-inc-res { justify-self: start; padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; background: #fef3c7; color: #92400e; }
.pv-inc-res.is-nack_7 { background: #fee2e2; color: #b91c1c; }
.pv-inc-res.is-test { background: #e0e7ff; color: #3730a3; }
.pv-inc-dev, .pv-inc-ap { grid-column: 1 / -1; color: var(--pv-text-soft); font-size: 13px; }
.pv-inc-empty { color: var(--pv-text-soft); }
.pv-inc-video { display: block; width: 100%; max-height: 70vh; background: #000; border-radius: 12px; }
.pv-inc-dl { display: grid; grid-template-columns: 6em 1fr; gap: 8px 12px; margin: 14px 0 0; font-size: 15px; }
.pv-inc-dl dt { color: var(--pv-text-soft); font-weight: 600; }
.pv-inc-dl dd { margin: 0; }
.pv-inc-dl small { color: var(--pv-text-mute); }
.pv-inc-res.is-dispense_fail, .pv-inc-res.is-timeout { background: #fee2e2; color: #b91c1c; }

/* 「ⓘ 설명」(public/js/preview/help.js, 2026-10-10) — 오류·상태 문구 옆 작은 ⓘ, 누르면 설명.
   ⓘ 는 글자색을 따라가는 옅은 회색 — 문구보다 눈에 띄면 안 된다. 누르는 자리는 28px(손가락).
   설명 창: 넓은 화면은 가운데 작은 카드, 휴대폰(≤560px)은 아래에서 올라오는 시트. 기존 모달(z 50) 위. */
.pv-help { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: -6px -4px -6px 0;
  padding: 0; border: 0; background: none; color: var(--pv-text-mute); cursor: pointer; vertical-align: middle; border-radius: 50%; }
.pv-help:hover, .pv-help:focus-visible { color: var(--pv-accent); background: rgba(37, 99, 235, .08); outline: none; }
.pv-issue-pill { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border: 1px solid #fde68a; border-radius: 999px;
  background: #fffbeb; color: #92400e; font: inherit; font-size: 12px; font-weight: 600; line-height: 1; cursor: pointer; white-space: nowrap; }
.pv-issue-pill:hover, .pv-issue-pill:focus-visible { border-color: #f59e0b; outline: none; }
.preview-card-issues { margin-top: 2px; }
.preview-txn-frame .pv-issue-pill { margin-left: 6px; }

.pv-help-layer { position: fixed; inset: 0; z-index: 80; display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(15, 15, 20, .45); }
.pv-help-sheet { position: relative; width: 100%; max-width: 380px; max-height: 80vh; overflow-y: auto; padding: 20px 20px 18px;
  background: var(--pv-surface); color: var(--pv-text); border-radius: 14px; box-shadow: 0 10px 40px rgba(0, 0, 0, .25); }
.pv-help-close { position: absolute; top: 8px; right: 8px; width: 36px; height: 36px; border: 0; background: none;
  color: var(--pv-text-soft); font-size: 16px; cursor: pointer; border-radius: 50%; }
.pv-help-close:hover, .pv-help-close:focus-visible { background: var(--pv-bg); outline: none; }
.pv-help-item + .pv-help-item { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--pv-border); }
.pv-help-title { margin: 0 36px 6px 0; font-size: 16px; font-weight: 700; }
.pv-help-title small { margin-left: 4px; font-size: 13px; font-weight: 500; color: var(--pv-text-soft); }
.pv-help-what { margin: 0 0 10px; font-size: 15px; line-height: 1.55; }
.pv-help-dl { margin: 0; font-size: 14px; line-height: 1.55; }
.pv-help-dl dt { margin-top: 8px; font-size: 12px; font-weight: 600; color: var(--pv-text-soft); }
.pv-help-dl dd { margin: 2px 0 0; }
.pv-help-dl ul { margin: 0; padding-left: 18px; }
.pv-help-detail { margin: 10px 0 0; padding: 8px 10px; border-radius: 6px; background: var(--pv-bg); font-size: 12px;
  color: var(--pv-text-soft); overflow-wrap: anywhere; }
@media (max-width: 560px) {
  .pv-help-layer { align-items: flex-end; padding: 0; }
  .pv-help-sheet { max-width: none; max-height: 85vh; border-radius: 16px 16px 0 0; padding-bottom: calc(22px + env(safe-area-inset-bottom)); }
}

/* 이슈 이력(store-events.js, 2026-10-11) — 지점 목록의 「이슈」 버튼 + 달력 창.
   버튼: 작은 외곽선 알약, 최근 7일 건수는 주황 배지(0이면 배지 없음). 카드 보기는 카드 오른쪽 위,
   목록 보기는 맨 오른쪽 칸. 카드가 통째로 링크라 버튼은 span[role=button] 이다(링크 안에 button 을 못 넣는다).
   달력 칸: 건수 숫자 + 옅은 주황 3단계(1~2 / 3~5 / 6+). 0건은 눌리지 않는 빈 칸.
   휴대폰(≤560px)은 창이 화면 전체. */
.pv-ev-btn { display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 10px; border: 1px solid var(--pv-border);
  border-radius: 999px; background: var(--pv-surface); color: var(--pv-text-soft); font-size: 12px; font-weight: 600; line-height: 1;
  white-space: nowrap; cursor: pointer; user-select: none; }
.pv-ev-btn:hover, .pv-ev-btn:focus-visible { border-color: #c9c9d1; color: var(--pv-text); outline: none; }
.pv-ev-badge { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: #fef3c7; color: #92400e;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; font-variant-numeric: tabular-nums; }
.preview-store-row { position: relative; }
.preview-store-row > .pv-ev-btn { position: absolute; top: 14px; right: 14px; }
.preview-store-row:has(> .pv-ev-btn) .preview-brand-name { padding-right: 84px; }
.preview-store-list.is-list.has-ev { grid-template-columns: minmax(0, 1fr) auto auto auto; }
.is-list .preview-store-row > .pv-ev-btn { position: static; justify-self: end; }
.is-list .preview-store-row:has(> .pv-ev-btn) .preview-brand-name { padding-right: 0; }
.is-list .pv-list-head .is-ev { text-align: right; }
.preview-page-head .pv-ev-btn { margin-left: 10px; vertical-align: middle; }

.pv-ev-modal .preview-modal-box { width: min(560px, 92vw); }
.pv-ev-modal .preview-modal-body { padding-bottom: 20px; }
.pv-ev-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 4px 0 12px; }
.pv-ev-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pv-ev-chip { height: 30px; padding: 0 11px; border: 1px solid var(--pv-border); border-radius: 999px; background: var(--pv-surface);
  color: var(--pv-text-soft); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.pv-ev-chip small { font-size: 11px; font-weight: 600; color: var(--pv-text-mute); font-variant-numeric: tabular-nums; }
.pv-ev-chip.is-on { background: var(--pv-text); border-color: var(--pv-text); color: #fff; }
.pv-ev-chip.is-on small { color: rgba(255, 255, 255, .7); }
.pv-ev-device { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--pv-text-soft); }
.pv-ev-device select { height: 30px; max-width: 220px; padding: 0 8px; border: 1px solid var(--pv-border); border-radius: var(--pv-radius-sm);
  background: var(--pv-surface); color: var(--pv-text); font: inherit; font-size: 13px; }
.pv-ev-calhead { justify-content: center; margin-bottom: 8px; }
.pv-ev-calhead .preview-cal-label { min-width: 7em; text-align: center; }
.pv-ev-cal { gap: 5px; }
.pv-ev-cell { appearance: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  min-height: 46px; padding: 4px 0; border: 1px solid var(--pv-border); border-radius: 8px; background: var(--pv-surface);
  font: inherit; color: var(--pv-text); cursor: pointer; }
.pv-ev-cell.is-empty { border: 0; background: none; cursor: default; }
.pv-ev-cell:disabled { cursor: default; color: var(--pv-text-mute); background: none; }
.pv-ev-cell.is-l1 { background: #fffbeb; border-color: #fde68a; }
.pv-ev-cell.is-l2 { background: #fef3c7; border-color: #fcd34d; }
.pv-ev-cell.is-l3 { background: #fde68a; border-color: #f59e0b; }
.pv-ev-cell.is-selected { border-color: var(--pv-text); box-shadow: 0 0 0 1px var(--pv-text) inset; }
.pv-ev-dnum { font-size: 11px; line-height: 1.1; color: var(--pv-text-soft); }
.pv-ev-cell:disabled .pv-ev-dnum { color: var(--pv-text-mute); }
.pv-ev-cnt { font-size: 15px; font-weight: 800; line-height: 1.1; color: #92400e; font-variant-numeric: tabular-nums; }
.pv-ev-dayhead { margin: 16px 0 0; padding-bottom: 6px; border-bottom: 1px solid var(--pv-border); font-size: 14px; font-weight: 700; }
.pv-ev-item .preview-hist-date b { font-weight: 600; color: var(--pv-text); }
.pv-ev-item .preview-hist-date small { font-size: 11px; color: var(--pv-text-mute); }
.pv-ev-item .preview-btn { flex: 0 0 auto; text-decoration: none; }
.pv-ev-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.preview-hist-tag.is-repeat { background: #fee2e2; color: #991b1b; }
.preview-hist-tag.is-done { background: #dcfce7; color: #166534; }
/* 「거래 보기」로 넘어온 행 — 잠깐 테두리로 짚는다. */
.preview-txn-row.is-deep { box-shadow: 0 0 0 2px var(--pv-accent) inset; border-radius: 6px; }
@media (max-width: 560px) {
  .pv-ev-modal { align-items: stretch; }
  .pv-ev-modal .preview-modal-box { width: 100vw; height: 100vh; height: 100dvh; max-height: none; border-radius: 0; }
  .pv-ev-cell { min-height: 42px; }
}

/* 매장 관리자 계정(본사 전용, 2026-10-20) — 지점 코드 줄 끝의 「계정 N」 알약(이슈 버튼과 같은 결, 더 작게).
   계정이 없으면 점선 테두리 「계정 없음」. 누르면 창: 계정마다 아이디·만든 날·마지막 로그인 + 「전송 양식 복사」. */
.pv-acct-btn { display: inline-flex; align-items: center; height: 20px; margin-left: 6px; padding: 0 8px; border: 1px solid var(--pv-border);
  border-radius: 999px; background: var(--pv-surface); color: var(--pv-text-soft); font-size: 11px; font-weight: 600; line-height: 1;
  white-space: nowrap; cursor: pointer; user-select: none; vertical-align: 1px; }
.pv-acct-btn:hover, .pv-acct-btn:focus-visible { border-color: #c9c9d1; color: var(--pv-text); outline: none; }
.pv-acct-btn.is-none { border-style: dashed; color: var(--pv-text-faint, #9a9aa3); }
.pv-acct-modal .preview-modal-box { width: min(520px, 92vw); }
.pv-acct-modal .preview-modal-body { padding-bottom: 20px; }
.pv-acct-item { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid var(--pv-border); }
.pv-acct-item:first-child { border-top: 0; }
.pv-acct-main { flex: 1; min-width: 0; }
.pv-acct-id { font-size: 15px; font-weight: 700; color: var(--pv-text); overflow-wrap: anywhere; }
.pv-acct-meta { margin-top: 3px; font-size: 12px; color: var(--pv-text-soft); }
.pv-acct-warn { margin-left: 6px; font-size: 11px; font-weight: 600; color: #b45309; }
.pv-acct-copy { flex: none; height: 34px; padding: 0 12px; border: 1px solid var(--pv-border); border-radius: 8px; background: var(--pv-surface);
  color: var(--pv-text); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.pv-acct-copy:hover { border-color: #c9c9d1; }
.pv-acct-copy.is-done { border-color: #86efac; background: #f0fdf4; color: #166534; }
@media (max-width: 560px) {
  .pv-acct-item { flex-wrap: wrap; }
  .pv-acct-copy { width: 100%; }
}
