[hidden] { display: none !important; }

:root {
  --red: #b5232c;
  --navy: #16213e;
  --cream: #faf6ee;
  --ink: #241f1f;
  --muted: #8a8078;
  --line: #e4ded2;
  --green: #1a8a44;
  --orange: #c07a12;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: "Noto Sans KR", "Noto Sans TC", -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--cream);
  color: var(--ink);
}
input, select, button, textarea { font-family: inherit; }

/* Login */
/* ── 관리자 로그인 화면 ──────────────────────────────────────────────
   홈페이지(Web/)와 같은 얼굴로 맞춘다. 2026-09-08에 홈페이지와 주문
   시스템이 한 주소로 합쳐지면서(src/site.js), 손님이 보는 화면과 이
   화면이 같은 사이트의 두 문이 됐다. 그런데 여기만 남색 배경에 흰
   카드, 빨간 버튼이라 다른 서비스로 넘어온 것처럼 보였다.

   색은 홈페이지의 다크 팔레트를 그대로 옮겼다 (Web/src/app/globals.css
   의 --bg/--panel/--gold/--muted 값). 여기서 CSS 변수로 다시 선언하지
   않고 실제 값을 쓰는 이유: 이 파일의 :root 에는 이미 관리자 대시보드용
   --navy/--red/--line 이 살고 있고, 대시보드는 밝은 화면 그대로 둬야
   한다. 로그인 화면에만 닫힌 스타일로 두는 편이 안전하다.

   대시보드(로그인 후)는 손대지 않았다 — 매일 몇 시간씩 보는 업무
   화면이라 밝은 쪽이 낫고, 이번 요청은 "로그인하는 페이지"였다. */
/* 지난번 로그인이 아직 살아 있으면 로그인 화면을 그리지 않는다. 위
   admin.html 의 인라인 스크립트가 이 표를 단다. 짐작이 틀렸으면
   showLogin() 이 표를 떼고 평소대로 보여준다. */
html[data-admin-seen="1"] #loginScreen { display: none; }

.login-screen {
  min-height: 100vh;
  display: flex;
  /* 세로 정중앙이 아니라 위쪽에 둔다. 태블릿처럼 세로로 긴 화면에서
     정중앙에 두면 위아래 여백이 과해져서 홈페이지 로그인 화면과 높이가
     안 맞는다 (그쪽도 헤더 아래에서 바로 시작한다). */
  align-items: flex-start;
  justify-content: center;
  padding: clamp(56px, 16vh, 170px) clamp(16px, 5vw, 48px) clamp(40px, 8vw, 72px);
  background: #0D0A08;
  /* 홈페이지 히어로의 아주 옅은 금빛 번짐 — 평평한 검정보다 덜 삭막하다 */
  background-image: radial-gradient(120% 80% at 50% 0%, rgba(200, 162, 75, 0.07), rgba(200, 162, 75, 0) 62%);
}
.login-shell { width: 100%; max-width: 400px; }

.login-brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; margin-bottom: 30px; }
.login-brand-mark {
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(200, 162, 75, 0.5);
  color: #C8A24B;
  font-family: 'Noto Serif TC', serif;
  font-size: 17px; line-height: 1;
}
.login-brand-name {
  font-family: 'Noto Serif TC', serif;
  font-size: 19px;
  letter-spacing: 0.16em;
  color: #F4EDE1;
}

.login-screen h1 {
  /* Newsreader 는 라틴 전용이라 한국어·중국어에는 적용되지 않는다(관리자
     화면은 이 두 언어뿐). 웹폰트를 받아봐야 한 글자도 안 쓰이므로 부르지
     않고, 기기에 있는 명조 계열로 간다 — 홈페이지 로그인 화면도 한국어에서는
     결국 같은 자리로 떨어진다. */
  font-family: 'Noto Serif KR', 'Apple SD Gothic Neo', serif;
  font-size: clamp(24px, 6vw, 31px);
  font-weight: 400;
  letter-spacing: 0.01em;
  color: #F4EDE1;
  margin: 0;
}
.login-sub { font-size: 13.5px; line-height: 1.6; color: rgba(239, 230, 216, 0.6); margin: 10px 0 0; }

.login-card {
  margin-top: 26px;
  padding: clamp(20px, 5vw, 30px);
  background: #15100C;
  border: 1px solid rgba(200, 162, 75, 0.18);
}

.login-field { display: block; margin-bottom: 18px; }
.login-field > span {
  display: block;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: #8C7A5E;
  margin-bottom: 7px;
}
.login-card input {
  width: 100%;
  box-sizing: border-box;
  padding: 13px 13px;
  background: #0D0A08;
  border: 1px solid rgba(200, 162, 75, 0.22);
  border-radius: 0;
  color: #F4EDE1;
  font-family: inherit;
  /* 16px 미만이면 모바일 브라우저가 입력칸을 탭할 때 화면을 확대해버린다.
     태블릿에서 손가락으로 누르는 칸이라 그것도 피할 겸 크게 잡는다. */
  font-size: 16px;
  letter-spacing: 0.06em;
  outline: none;
  transition: border-color 0.18s ease;
}
.login-card input:focus { border-color: rgba(200, 162, 75, 0.55); }

.login-card button {
  width: 100%;
  padding: 13px 0;
  border: none;
  border-radius: 0;
  background: #C8A24B;
  color: #0D0A08;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.08em;
  cursor: pointer;
  transition: background 0.18s ease;
}
.login-card button:hover { background: #E0C179; }

/* 비밀번호가 틀렸을 때. 빨강을 그대로 쓰면 이 화면에서 혼자 튀어서,
   금색 계열 안에서 읽히는 낮은 채도의 붉은 톤으로 맞췄다. */
.login-error {
  color: #D98A72;
  font-size: 13px;
  line-height: 1.5;
  margin-top: 14px;
  text-align: center;
}

.login-back { margin: 22px 0 0; font-size: 12.5px; }
.login-back a { color: #C8A24B; text-decoration: none; letter-spacing: 0.04em; }
.login-back a:hover { color: #E0C179; }

/* Top bar */
.admin-topbar { background: var(--navy); color: #fff; display: flex; align-items: center; padding: 0 20px; height: 58px; gap: 24px; position: sticky; top: 0; z-index: 30; }
.admin-brand { font-weight: 900; }
/* 탭이 하나 늘어날 때마다(2026-09-08 '계정' 탭) 좁은 화면에서 탭 이름이
   '메뉴 관/리' 처럼 단어 중간에서 줄바꿈되던 문제 — 이름은 절대 쪼개지
   않게 하고, 자리가 모자라면 탭 줄이 가로로 스크롤되게 한다. */
.admin-tabs { display: flex; gap: 6px; flex: 1; overflow-x: auto; scrollbar-width: thin; }
.admin-tabs button { background: transparent; border: none; color: #cfd3e0; padding: 10px 14px; border-radius: 8px; cursor: pointer; font-size: 18px; display:flex; align-items:center; gap:6px; white-space: nowrap; flex: 0 0 auto; }
.admin-tabs button.active { background: rgba(255,255,255,0.12); color: #fff; font-weight: 700; }
/* 패드 폭에서 탭이 잘리던 것(2026-09-29 사장님 패드 사진: 「회원(VIP)」 뒤가
   「ㄱ」 하나만 보였다). 가로로 밀면 보이긴 하지만 패드에서는 밀어야 한다는
   걸 알 길이 없다 — 폭이 모자라면 글자·간격을 줄여 한 줄에 다 들어가게 한다. */
@media (max-width: 1360px) {
  .admin-topbar { gap: 14px; padding: 0 14px; }
  .admin-tabs { gap: 2px; }
  .admin-tabs button { font-size: 16px; padding: 8px 10px; }
}
@media (max-width: 1100px) {
  /* 「한국관 관리자」 글자는 태극 아이콘만 남긴다 — 탭 자리가 더 급하다. */
  .admin-brand { font-size: 0; }
  .admin-brand img { margin-right: 0 !important; width: 20px; height: 20px; }
  .admin-tabs button { font-size: 15px; padding: 8px 7px; }
  .logout-btn { padding: 6px 10px; }
}
/* 세로로 세운 패드(폭 900 이하) — 한 줄에는 다 안 들어간다. 탭을 제목 줄
   아래 한 줄로 내리고, 그래도 모자라면 두 줄로 접는다(가로로 밀게 두지 않는다). */
@media (max-width: 900px) {
  .admin-topbar { flex-wrap: wrap; height: auto; padding: 6px 12px; row-gap: 4px; }
  .admin-brand { margin-right: auto; }
  .admin-tabs { order: 3; flex: 1 0 100%; flex-wrap: wrap; overflow-x: visible; }
}
.badge-count { background: var(--red); color: #fff; border-radius: 999px; font-size: 14px; padding: 1px 7px; }
.logout-btn { background: transparent; border: 1px solid rgba(255,255,255,0.3); color: #fff; padding: 8px 14px; border-radius: 8px; cursor: pointer; }
.admin-lang-switch { display: flex; gap: 4px; }
.admin-lang-btn { background: transparent; border: 1px solid rgba(255,255,255,0.3); color: #cfd3e0; padding: 6px 10px; border-radius: 8px; cursor: pointer; font-size: 16px; }
.admin-lang-btn.active { background: rgba(255,255,255,0.16); color: #fff; font-weight: 700; }

.admin-main { padding: 20px; max-width: 1600px; margin: 0 auto; }
.tab-panel { }

/* Orders board */
.orders-toolbar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px 16px; margin-bottom: 14px; font-size: 18px; }
/* 2026-09-29 사장님 패드 화면: 「신규 / 주문 알림음」이 두 줄로 꺾였다. 체크박스
   글자는 꺾지 않는다. 「자동 인쇄 중」 줄은 아래 한 줄을 통째로 쓴다. */
.orders-toolbar > label { white-space: nowrap; }
.orders-toolbar { justify-content: flex-start; }
.orders-toolbar-actions { display: inline-flex; gap: 8px; margin-left: auto; white-space: nowrap; }
.orders-toolbar button { padding: 8px 14px; border-radius: 8px; border: 1px solid var(--line); background: #fff; cursor: pointer; }
#refreshOrders { min-width: 110px; transition: background-color 0.15s, border-color 0.15s; }
#refreshOrders:disabled { cursor: default; }
#refreshOrders.is-loading { background: #f3f1ea; color: var(--muted); }
#refreshOrders.is-done { background: #e6f4ea; border-color: var(--green); color: #1e7e34; font-weight: 700; }
.orders-board { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.order-col { background: #f2ede2; border-radius: 12px; padding: 10px; min-height: 200px; }
.order-col h3 { margin: 4px 6px 10px; font-size: 18px; display: flex; align-items: center; gap: 6px; }
.col-count { color: var(--muted); font-weight: 400; }
.paid-settlement-row { display: flex; gap: 6px; margin: 0 6px 10px; }
.settle-quick-btn {
  flex: 1; padding: 6px 4px; font-size: 12px; font-weight: 700; border-radius: 8px;
  border: 1px solid #d8cfba; background: #fff; cursor: pointer;
}
.settle-quick-btn:hover { background: #f6ead2; }
.order-card {
  background: #fff; border-radius: 10px; padding: 10px; margin-bottom: 8px; cursor: pointer;
  border-left: 4px solid var(--red); box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
.order-col[data-status="preparing"] .order-card { border-left-color: var(--orange); }
.order-col[data-status="served"] .order-card { border-left-color: var(--green); }
.order-col[data-status="paid"] .order-card { border-left-color: var(--muted); }
.order-card-top { display: flex; justify-content: space-between; font-weight: 700; font-size: 17px; margin-bottom: 4px; }
.order-card-time { color: var(--muted); font-weight: 400; font-size: 14px; }
.order-card-items { font-size: 16px; color: #55504a; margin-bottom: 6px; line-height: 1.5; }
.order-card-total { font-weight: 700; font-size: 17px; }
/* 할인이 걸린 결제완료 주문은 **받은 돈**을 크게 적고, 할인 전 금액과
   깎아준 돈을 그 아래 작게 붙인다. 2026-09-16 사장님: "직원이 할인여부 등
   당일 정산에 대한 오류검증, 또는 손님이 할인여부에 대한 재확인 요구시
   할인여부를 현재로서는 확인하기 힘든 상황." — 받은 돈만 있으면 "왜 470이
   아니라 447이지" 가 되고, 할인 전 금액만 있으면 서랍과 안 맞는다. 둘 다
   있어야 그 자리에서 검산이 된다. */
.order-card-total-was {
  display: block;
  margin-top: 2px;
  font-weight: 500;
  font-size: 12px;
  color: #6b7280;
}
/* Squeezing every button (다음 단계/취소/수정/인쇄/미리보기) into one flex
   row forced each into a sliver too narrow for its label, wrapping "결제
   완료로 변경" onto three lines and leaving the buttons looking crammed
   together — a 2-column grid gives each one real width and breathing
   room, with the 다음 단계 button (the main action, and usually the
   longest label) spanning the full row above the rest. */
.order-card-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px; }
.order-card-actions button {
  font-size: 14px; padding: 9px 6px; border-radius: 8px; border: 1px solid var(--line);
  background: #f7f5f0; cursor: pointer; line-height: 1.3;
}
.order-card-actions button.primary { grid-column: 1 / -1; padding: 10px 6px; font-weight: 700; background: var(--navy); color: #fff; border-color: var(--navy); }
.order-card.flash { animation: flash 1.2s ease-in-out 2; }
.order-card-type-badge {
  display: inline-block; margin-left: 8px; vertical-align: middle;
  font-size: 12px; font-weight: 700; padding: 1px 9px; border-radius: 999px;
}
.order-card-type-badge.takeout { background: #fff3cd; color: #8a6100; border: 1px solid #e3c07a; }
.order-card-type-badge.delivery { background: #dbeafe; color: #1e429f; border: 1px solid #93b8f5; }
.order-card-type-badge.mixed { background: #f3e8ff; color: #6b21a8; border: 1px solid #d3b3f0; }

/* Print-failure banner + card badge — see printKitchenTicket()/
   markPrintFailed()/renderPrintFailureBanner() in admin.js. Deliberately
   loud and non-auto-dismissing: a printer failing silently is otherwise
   indistinguishable from "no order came in" to kitchen staff who only
   watch the paper. */
.print-fail-banner {
  background: #fdecea; border: 1px solid var(--red); color: var(--red); font-weight: 700;
  font-size: 15px; line-height: 1.5; padding: 12px 16px; border-radius: 10px; margin-bottom: 14px;
}
.order-card.print-failed { border-left-color: var(--red); box-shadow: 0 0 0 2px rgba(181,35,44,0.35); }
.order-card-print-fail {
  background: #fdecea; color: var(--red); font-size: 13px; font-weight: 700;
  padding: 5px 8px; border-radius: 6px; margin-bottom: 6px; line-height: 1.4;
}
@keyframes flash { 0%,100% { box-shadow: 0 1px 3px rgba(0,0,0,0.06);} 50% { box-shadow: 0 0 0 4px rgba(181,35,44,0.35);} }

/* Menu management */
.menu-toolbar { margin-bottom: 14px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
/* 휴지통은 곁들이다. 「메뉴 추가」와 같은 빨강이면 둘 다 중요해 보인다. */
.menu-toolbar .ghost-btn {
  background: #fff; color: var(--muted); border: 1px solid var(--line); font-weight: 700;
}
.menu-toolbar button, .tables-toolbar button, .print-qr-btn {
  padding: 10px 16px; border-radius: 8px; border: none; background: var(--red); color: #fff; cursor: pointer; font-weight: 700; text-decoration: none; display: inline-block; font-size: 17px;
}
.cat-block { margin-bottom: 26px; }
.cat-block h3 { font-size: 21px; margin-bottom: 8px; }
.item-table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 10px; overflow: hidden; }
.item-table th, .item-table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); font-size: 17px; }
.item-table th { background: #f2ede2; font-weight: 700; color: var(--muted); font-size: 16px; }
.item-row-photo { width: 44px; height: 44px; border-radius: 8px; background: #eee; background-size: cover; background-position: center; display: inline-block; vertical-align: middle; }
.photo-missing-badge {
  width: 44px; height: 44px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
  vertical-align: middle; border: 1.5px dashed var(--red); color: var(--red); font-size: 10px; font-weight: 700;
  line-height: 1.2; text-align: center; background: #fdf0ef;
}
/* 품절 배지 — 수정 권한이 있으면 버튼이라 눌러서 바로 품절 설정을 연다.
   글자 크기·색은 예전 그대로 두고(직원들이 이미 그 모양으로 알아본다)
   누를 수 있다는 것만 손끝에 전해지도록 테두리와 커서를 준다. */
.availability-pill { padding: 3px 10px; border-radius: 999px; font-size: 14px; font-weight: 700; }
button.availability-pill {
  border: 1px solid transparent;
  font-family: inherit;
  cursor: pointer;
  min-height: 30px;
}
button.availability-pill:hover { border-color: currentColor; }
/* 배지 밑의 "9월 12일까지" 같은 한 줄 — 표에서 하나씩 열어보지 않아도
   언제 풀리는지 보이게 한다. */
.soldout-note { margin-top: 3px; font-size: 13px; color: var(--muted); }
/* 「9/11 11:00 풀림」. 날짜 범위 바로 아래에 한 줄 더 붙는다 — 언제 풀리는지
   모르면 그 날짜가 지난 아침에 「고장났나」로 읽힌다(2026-09-11). */
.soldout-release { margin-top: 2px; font-size: 12px; color: #6b7280; }

/* 「저장 안 된 변경이 있어요」 (2026-09-11 사장님: "누르는 즉시 저장되는
   카드 — 이것도 그냥 저장 누르게 만들어줘").

   눌러야 저장되게 바꾸면 안 누르고 나가서 잃을 수 있다. 즉시 저장은 그
   위험이 없던 대신 저장한 티가 안 났다. 둘 다 챙기려면 아직 안 눌렀다는
   것이 그 자리에 보여야 한다 — 그래서 버튼도 같이 빨개진다. */
.settings-dirty {
  margin-top: 8px;
  font-size: 14px;
  font-weight: 700;
  color: var(--red);
}
/* 칸 옆의 작은 되돌리기 버튼 (2026-09-11 사장님: "기본값 버튼을 만들어서
   디폴트로 다시 되돌리게 해줘. 시간 넣었다가 변경하려고 할 때 방법이 없어서").

   <input type="time"> 과 <input type="date"> 는 한 번 값을 넣으면 다시
   비우는 방법이 브라우저마다 다르고, 가게 태블릿에서는 아예 없다시피 하다.
   그래서 비우는 길을 화면에 직접 둔다. */
.field-with-reset { display: flex; align-items: center; gap: 8px; }
.field-with-reset input { flex: 1; min-width: 0; }
.field-reset-btn {
  flex: 0 0 auto;
  margin-top: 4px;
  padding: 9px 14px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--muted);
  border-radius: 8px;
  cursor: pointer;
  font-weight: 700;
  font-size: 14px;
  white-space: nowrap;
}
.field-reset-btn:hover { background: #f3f3f3; color: var(--ink); }
/* .settings-hint 는 제목에 붙으라고 margin-top 이 -6px 이다. 칸 줄 바로 뒤에
   오는 안내는 그 음수를 걷어내야 글자가 안 겹친다. */
.field-with-reset + .settings-hint { margin-top: 8px; }
/* 세로로 쌓인 칸(품절 날짜)에서는 칸 바로 아래 오른쪽에 붙인다. */
label > .field-reset-btn { display: block; margin-left: auto; margin-top: 6px; }

.settings-card button.is-dirty {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

/* 품절 설정 팝업의 네 가지 선택지 */
.soldout-modes { display: flex; flex-direction: column; gap: 8px; }
.soldout-mode {
  text-align: left;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  font-family: inherit;
  font-size: 16px;
  min-height: 46px;
  cursor: pointer;
}
.soldout-mode:hover { border-color: var(--navy); }
.soldout-mode.on { border-color: var(--navy); background: var(--navy); color: #fff; }
.availability-pill.on { background: #e7f6ec; color: var(--green); }
.availability-pill.off { background: #f4e4e4; color: var(--red); }
.item-table tr { cursor: pointer; }
.item-table tr:hover { background: #fbf8f2; }

/* Tables */
.tables-toolbar { display: flex; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; align-items: center; }
.tables-toolbar input { padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; font-size: 17px; }
.tables-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; }
.table-chip { background: #fff; border: 1px solid var(--line); border-radius: 10px; padding: 12px; text-align: center; position: relative; cursor: pointer; }
.table-chip:hover { border-color: var(--muted); }
.table-chip.has-order { border-color: var(--red); background: #fdf3f2; }
.table-chip .num { font-weight: 800; font-size: 21px; }
.table-chip .del-btn { position: absolute; top: 4px; right: 6px; border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 17px; }
.table-order-badge { margin-top: 6px; font-size: 14px; font-weight: 700; padding: 3px 8px; border-radius: 999px; display: inline-block; }
.table-order-badge.active { background: var(--red); color: #fff; }
.table-order-badge.empty { background: #f2ede2; color: var(--muted); font-weight: 500; }
.table-party-badge { margin-top: 4px; font-size: 14px; color: var(--muted); font-weight: 600; }
/* 태블릿 한 화면 기준으로 짠다.
 *
 * 2026-09-16 사장님: "테블릿 가로 세로 넓이를 항상 고려해줬으면 좋겠어.
 * 지금 모든 창이나 그런 걸 태블릿이 주로 돌아간다고 생각하면 좋을 것
 * 같아. 테블릿 한 화면 안에 왠만하면 전체가 들어왔으면 좋겠어."
 *
 * 폭: 480px 은 할인이 걸리는 순간 좁았다. 금액 칸이 「NT$230 NT$207」로
 * 두 배가 되면서 메뉴 이름을 밀어냈다 — "글자 많아져서 왼쪽으로 빠지는데
 * 오른쪽이 고정이 되었으면 좋겠어. 그래서 차라리 처음부터 그 공간을
 * 고려해서 넓직하게." 할인이 걸리든 안 걸리든 자리가 안 움직이도록,
 * 처음부터 그만큼 잡아둔다. 720px 은 태블릿 세로(768px)에도 들어간다.
 *
 * 높이: 모달 전체가 스크롤되면 「결제 완료」 버튼이 목록 끝까지 내려가야
 * 나온다. 주문이 많은 자리일수록 그렇다 — 정작 제일 자주 누르는 버튼이
 * 제일 찾기 어려워진다. 그래서 세로 flex 로 짜고 **가운데 목록만** 굴린다
 * (아래 .table-detail-scroll). 머리(테이블 번호·미결제 합계·탭)와
 * 발(미결제 합계·결제 완료)은 늘 같은 자리에 붙어 있다. */
/* .modal 이 뒤에서 max-width:560px 을 주므로(같은 한 칸짜리 선택자라 나중
   것이 이긴다) 여기서 .modal 을 같이 적어 더 구체적으로 만든다. 이걸 안
   하면 아래 720px 이 조용히 무시된다 — 예전 480px 도 사실 안 먹고 있었다. */
.modal.table-detail-modal {
  max-width: 720px;
  display: flex;
  flex-direction: column;
  overflow: hidden; /* 굴리는 것은 안쪽 .table-detail-scroll 하나뿐 */
}
.table-detail-modal > #tableDetailBody {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0; /* 없으면 flex 자식이 안 줄어들어 스크롤이 안 생긴다 */
}
.table-detail-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* 굴러가는 내용이 발밑으로 사라지는 경계를 눈에 보이게 */
  padding-bottom: 4px;
}
/* 발은 늘 바닥에. 사장님: "저 미결제 합계랑 결제완료 의 가장 아래 행은
   스크롤 안되고 중간에 있는 메뉴들만 스크롤로 해서 결제완료 행은 언제든
   고정된 위치에서 편하게 누를 수 있게 하는 게 맞는 거 같아." */
.table-detail-modal .table-detail-footer {
  flex: none;
  background: #fff;
}

/* 금액 칸은 **폭이 고정**이다.
 *
 * 할인이 걸리면 「NT$230」이 「NT$230 NT$207」이 된다. 폭을 안 잡아두면 그
 * 두 배가 된 칸이 메뉴 이름 쪽을 밀어서, 할인을 켜고 끌 때마다 줄이
 * 좌우로 출렁인다. 그리고 품목 줄·소계·합계·미결제 합계의 숫자가 서로
 * 다른 세로선에 서서 눈으로 훑어 검산할 수가 없다.
 *
 * 처음부터 「NT$230 NT$207」이 들어갈 만큼 잡아두고 오른쪽 정렬한다.
 * 할인이 없는 평소에는 그냥 빈 자리로 남는다 — 그게 목적이다. */
.pay-amount-cell {
  flex: 0 0 auto;
  min-width: 168px;
  text-align: right;
  white-space: nowrap;
}
/* 소계 / 합계 줄. 라벨은 왼쪽, 숫자는 위 금액 칸과 **같은 세로선**에. */
.pay-total-row {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 10px;
}
@media (max-width: 560px) {
  /* 폰에서는 168px 을 고집하면 메뉴 이름이 짓눌린다. */
  .pay-amount-cell { min-width: 0; }
}
/* 주문이 여러 건이라 아래 .order-block-grid가 뜨는 화면은 카드가 최소한
   한 줄에 하나씩은 여유 있게 들어가야 "각자 독립된 창"처럼 보이므로,
   480px보다 훨씬 넓혀준다(JS의 openTableDetail에서 isGrid일 때만 이
   클래스를 붙임 — 주문이 1건뿐이거나 특정 주문 하나만 볼 때는 원래
   폭 그대로). */
.table-detail-modal.wide { max-width: 1040px; }

/* 테이블 상세(결제) 모달 안의 주문 카드 — 2026-09-05 사장님 피드백(두
   차례): "지금 한 창에 다른 여러개의 주문들이 섞여 있잖아. 차라리 각
   주문들의 창을 한 열 행으로 이어붙여서 여러개 할 수 있으면 좋을 거
   같아" → 그 다음 "이 엑스하는 창 같은 걸 따로따로 다 만들어달라는
   거였어. 옆으로 위아래로 이어 붙여서. 그러면 완전 다른 거라고 인식하기
   편하고". 서로 무관한 손님 여러 명의 주문(포장 카운터가 대표 사례)을
   한 눈에 "완전 다른 것"으로 알아보게 하려면 카드 하나하나가 이 모달
   자체처럼(자기만의 테두리·그림자·✕ 버튼이 있는 독립된 "창") 보여야
   하고, 한 줄로만 이어지는 게 아니라 옆으로도 위아래로도 줄바꿈되는
   격자로 늘어놓아야 한다. */
/* 2026-09-05 "모든 게 규격이 같았으면 좋겠어 예를들어 결제 완료로 변경,
   수정 위치랑 소계 위치랑 이런 거" — 세로 flex로 만들어서, 카드 안
   맨 아래 소계 줄(admin.js의 renderTableOrderBlock, margin-top:auto)이
   품목 수와 상관없이 항상 카드 맨 아래에 붙게 한다. 격자 안에서는
   .order-block-grid가 한 줄의 카드 높이를 자동으로 맞춰주므로(그리드
   기본 동작인 align-items: stretch), 그 안에서 소계가 항상 같은 위치에
   오게 된다. */
.table-order-block { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 10px; padding: 14px; margin-bottom: 12px; background: #fff; position: relative; }
/* withDismiss일 때(주문 2건 이상)만 붙는 수정자 — 그림자를 더 줘서 뒤에
   깔린 다른 카드와 확실히 분리된 "창"처럼 보이게 한다. */
.table-order-block-windowed { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); padding-top: 34px; }
.table-order-block-dismiss {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 999px;
  background: #f1ede6;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
.table-order-block-dismiss:hover { background: #e6e0d4; color: var(--ink); }
.order-block-grid {
  display: grid;
  /* 2026-09-05 "좌우 너비가 너무 좁아" 피드백 — 260px는 라벨(픽업번호·
     이름·시간)이 길면 버튼 쪽이 짓눌릴 만큼 좁았다. 320px로 넓히고(위
     .table-order-block-windowed 헤더도 라벨/버튼을 위아래로 나눠 같이
     고침) 모달 폭(.table-detail-modal.wide)도 함께 늘림. */
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 14px;
  margin-bottom: 4px;
}
.order-block-grid .table-order-block { margin-bottom: 0; }

/* 포장 카운터 QR box — a separate, non-table order source (see
   renderCounterSection in admin.js), so it sits in its own card above the
   regular table grid rather than mixed into it. */
.counter-section:empty { display: none; }
.counter-card {
  display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap;
  background: #fff; border: 1px dashed var(--navy); border-radius: 10px; padding: 14px 16px; margin-bottom: 16px; cursor: pointer;
}
.counter-card:hover { background: #f7f8fd; }
.counter-card-empty { cursor: default; }
.counter-card-empty:hover { background: #fff; }
.counter-card-text strong { font-size: 17px; }
.counter-card-text p { margin: 4px 0 0; font-size: 14px; color: var(--muted); }
.counter-card-right { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.counter-card-right .print-qr-btn { font-size: 14px; padding: 8px 14px; }

/* 합산 결제 (multi-table combined payment) — see mergePayMode in admin.js.
   Only tables with an unpaid order are selectable; picking several and
   confirming pays every one of their unpaid orders off in one action,
   same as if 전체 결제 완료 had been pressed on each table individually. */
.table-chip.merge-selectable { cursor: pointer; }
.table-chip.merge-selectable:hover { border-color: var(--navy); }
.table-chip.merge-selected { border-color: var(--navy); background: #eef1fb; box-shadow: 0 0 0 2px var(--navy); }
.table-chip.merge-disabled { opacity: 0.4; cursor: not-allowed; }
.table-chip .merge-checkbox {
  position: absolute; top: 4px; left: 6px; width: 18px; height: 18px; border: 2px solid var(--muted);
  border-radius: 4px; background: #fff; font-size: 13px; line-height: 14px; color: #fff; font-weight: 800;
}
.table-chip.merge-selected .merge-checkbox { background: var(--navy); border-color: var(--navy); }
.merge-pay-bar {
  position: sticky; bottom: 12px; margin-top: 14px; background: #fff; border: 2px solid var(--navy);
  border-radius: 12px; padding: 14px 18px; display: flex; justify-content: space-between; align-items: center;
  gap: 14px; box-shadow: 0 -2px 10px rgba(0,0,0,0.1); font-weight: 700; font-size: 15px; flex-wrap: wrap;
}
.merge-pay-actions { display: flex; gap: 8px; }

/* Floor plan (배치도) */
.view-toggle { display: flex; gap: 8px; margin-bottom: 14px; }
.view-toggle-btn {
  padding: 8px 14px; border-radius: 8px; border: 1px solid var(--line); background: #fff;
  cursor: pointer; font-size: 17px; font-weight: 600; color: var(--muted);
}
.view-toggle-btn.active { background: var(--navy); color: #fff; border-color: var(--navy); }
.floor-plan-wrap { margin-top: 4px; }
.floor-plan {
  position: relative; width: 100%; min-height: 620px; overflow: auto;
  background-color: #fbf9f4;
  background-image: linear-gradient(rgba(0,0,0,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0,0,0,0.05) 1px, transparent 1px);
  background-size: 20px 20px;
  border: 1px solid var(--line); border-radius: 12px;
}
.zone-block {
  position: absolute; background: rgba(22,33,62,0.05); border: 2px dashed var(--muted);
  border-radius: 10px; box-sizing: border-box; user-select: none;
}
.zone-label {
  position: absolute; top: 6px; left: 8px; font-size: 12px; font-weight: 700; color: var(--muted);
  background: #fbf9f4; padding: 2px 6px; border-radius: 6px; cursor: text; pointer-events: auto;
}
.zone-del { position: absolute; top: 4px; right: 4px; border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 12px; }
.zone-add-btn {
  position: absolute; top: 4px; right: 24px; border: 1px solid var(--red); background: #fff; color: var(--red);
  cursor: pointer; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
}
.table-unassign {
  position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; border-radius: 999px;
  border: 1px solid var(--line); background: #fff; color: var(--muted); cursor: pointer; font-size: 10px;
  line-height: 1; display: flex; align-items: center; justify-content: center; z-index: 6;
}
.resize-handle {
  position: absolute; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize;
  background: linear-gradient(135deg, transparent 50%, var(--muted) 50%); border-radius: 0 0 8px 0; opacity: 0.6;
}
.table-block {
  position: absolute; background: #fff; border: 2px solid var(--line); border-radius: 10px;
  box-sizing: border-box; display: flex; align-items: center; justify-content: center;
  flex-direction: column; cursor: grab; font-weight: 800; font-size: 13px; box-shadow: 0 2px 6px rgba(0,0,0,0.08);
  user-select: none; z-index: 5;
}
.table-block:active { cursor: grabbing; }
/* 끄는 동안 지금 자리가 옆 테이블과 겹치는 상태. 손을 떼면 그 앞의 빈
   자리로 물러난다 — 왜 거기 안 놓이는지 미리 보여주는 표시다.
   (2026-09-16: 예전에는 겹치는 순간 그 자리에 붙들어서, 옆 테이블 너머로
   옮기는 것 자체가 불가능했다.) */
.table-block.table-block-blocked { border-color: var(--red); border-style: dashed; opacity: 0.6; }
.table-block.has-order { border-color: var(--red); background: #fdf3f2; }
.table-block .tb-party { font-size: 9px; font-weight: 600; color: var(--muted); margin-top: 1px; }
/* 결제탭의 완전 포장(order_type === "takeout") 주문 타일 — 포장 카운터든
   진짜 테이블이든, 미결제 포장 주문 수만큼 옆으로 늘어놓는 타일 각각에
   붙는 태그(포장 카운터는 "📦 3번 · 홍길동", 진짜 테이블은 "📦 포장") —
   기본 글자 크기로는 타일 폭에 안 들어가서 tb-party와 같은 방식으로 작게,
   여러 줄로 감싸이게 표시. */
.table-block .tb-counter-tag {
  font-size: 9px; font-weight: 600; color: var(--muted); margin-top: 2px;
  text-align: center; line-height: 1.2; padding: 0 3px; white-space: normal; word-break: keep-all;
}
/* 시험용 자리(2026-09-16 「테스트 테이블」) — 바쁠 때 진짜 자리로 착각해
   여기에 손님 주문을 넣으면 그 돈은 결산에 안 잡힌다. 빗금으로 「이건 진짜
   자리가 아니다」를 멀리서도 보이게 한다. */
.table-block.test-table {
  border-style: dashed;
  background-image: repeating-linear-gradient(
    45deg,
    rgba(120, 120, 130, 0.09) 0 6px,
    transparent 6px 12px
  );
}
.table-block .tb-test-tag {
  font-size: 9px;
  font-weight: 700;
  color: var(--muted);
  margin-top: 1px;
  letter-spacing: 0.02em;
}
.table-block .resize-handle { background: linear-gradient(135deg, transparent 50%, var(--red) 50%); }
/* 결제 탭 배치도(payment-floor-plan)는 항상 보기 전용 — 좌석을 잡아서
   옮기는 게 아니라 터치해서 결제 화면을 여는 용도라, 기본 .table-block의
   grab 커서 대신 pointer로 표시한다 (item 22). */
/* 결제 탭 배치도는 남는 자리에 꽉 차게 키운다 (2026-09-13 사장님: "결제
   화면을 화면에 꽉차게 키워줄 수 있어?"). 확대는 안쪽 .floor-stage 에만
   걸고, 바깥 칸은 그 크기에 맞춰 자바스크립트가 높이를 잡는다
   (admin.js fitPaymentFloorPlan). 확대한 뒤에도 스크롤이 생기면 안 되므로
   넘치는 것은 숨긴다 — 어차피 화면에 맞춰 줄인 것이라 잘릴 것이 없다. */
.payment-floor-plan { overflow: hidden; min-height: 0; }
.floor-stage { position: absolute; top: 0; left: 0; transform-origin: top left; }
.payment-floor-plan .table-block { cursor: pointer; }
.payment-floor-plan .table-block:active { cursor: pointer; }
.payment-floor-plan .zone-block { cursor: default; }
.align-guide { position: absolute; pointer-events: none; z-index: 50; }
.align-guide-v { width: 0; border-left: 1.5px dashed #2f80ed; }
.align-guide-h { height: 0; border-top: 1.5px dashed #2f80ed; }

/* Size-match markers: drawn independently on both tables' edges when a
   resize makes their width/height equal — solid, and deliberately not
   connected to each other (unlike the dashed alignment guide above). */
.size-match-mark { position: absolute; pointer-events: none; z-index: 50; }
.size-match-mark-v { width: 0; border-left: 2px solid #2f80ed; }
.size-match-mark-h { height: 0; border-top: 2px solid #2f80ed; }

/* Settings — a left-hand category nav plus a scrolling content column, so
   the (now fairly large) pile of settings cards isn't all shown at once. */
.settings-shell { display: flex; align-items: flex-start; gap: 32px; max-width: 1320px; margin: 0 auto; }
.settings-nav { display: flex; flex-direction: column; gap: 4px; flex: 0 0 168px; position: sticky; top: 16px; }
.settings-nav { flex: 0 0 200px; }
.settings-nav-btn {
  display: block;
  width: 100%;
  background: transparent; border: none; text-align: left; color: var(--muted); padding: 9px 14px;
  border-radius: 8px; cursor: pointer; font-size: 16px; font-weight: 600;
}
.settings-nav-btn:hover { background: #f0f0f0; }
.settings-nav-btn.active { background: var(--navy); color: #fff; }
.settings-nav-btn .nav-name { display: block; }
/* 무엇이 들어 있는 분류인지 한 줄로 적어준다. 이름만으로는 「매장 정보」와
   「주문 규칙」 중 어디에 영업시간이 있는지 알 수 없다. */
.settings-nav-btn .nav-sub { display: block; font-size: 13px; font-weight: 400; opacity: 0.72; margin-top: 2px; }
.settings-nav-btn.active .nav-sub { opacity: 0.78; }

/* 설정 찾기 */
.settings-search { position: relative; max-width: 1320px; margin: 0 auto 18px; }
.settings-search input {
  width: 100%; max-width: 460px; padding: 11px 14px; font-size: 17px; font-family: inherit;
  border: 1px solid var(--line); border-radius: 10px; background: #fff;
}
.settings-search-results {
  position: absolute; z-index: 30; margin-top: 4px; width: 100%; max-width: 460px;
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); overflow: hidden; max-height: 320px; overflow-y: auto;
}
.settings-search-hit {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  width: 100%; padding: 11px 14px; background: transparent; border: none; border-bottom: 1px solid #f0ece6;
  text-align: left; cursor: pointer; font-family: inherit;
}
.settings-search-hit:last-child { border-bottom: none; }
.settings-search-hit:hover, .settings-search-hit:focus { background: #f6f2ea; }
.settings-search-hit .hit-name { font-size: 16px; font-weight: 600; color: var(--ink); }
.settings-search-hit .hit-cat { font-size: 14px; color: var(--muted); white-space: nowrap; }
.settings-search-empty { padding: 12px 14px; font-size: 15px; color: var(--muted); }
/* 찾아서 데려온 카드를 잠깐 짚어준다 — 분류만 바뀌고 끝나면 화면 어디를
   봐야 하는지 여전히 알 수 없다. */
@keyframes settingsFound {
  from { box-shadow: 0 0 0 3px var(--navy); }
  to { box-shadow: 0 0 0 3px rgba(0, 0, 0, 0); }
}
.settings-card.is-found { animation: settingsFound 1.6s ease-out; }
.settings-content { flex: 1; min-width: 0; }
.settings-card { background: #fff; border-radius: 12px; padding: 20px; max-width: 880px; margin: 0 0 20px; }
.settings-card h3 { margin-top: 0; }
.settings-card label { display: block; font-size: 16px; color: var(--muted); margin-bottom: 12px; }
.settings-card input, .settings-card textarea, .settings-card select { width: 100%; padding: 10px; border: 1px solid var(--line); border-radius: 8px; margin-top: 4px; font-size: 18px; font-family: inherit; resize: vertical; }
.settings-card button { padding: 10px 18px; border: none; background: var(--navy); color: #fff; border-radius: 8px; cursor: pointer; font-weight: 700; }
.save-msg { color: var(--green); font-size: 16px; margin-top: 10px; }
/* 알림음/자동 인쇄 체크박스는 orders-toolbar에 인라인으로 붙어있어 위
   .save-msg(카드 하단용, margin-top 10px)를 그대로 쓰면 툴바 안에서 어긋나
   보여서 인라인 전용으로 따로 뺌 — 2026-09-06, "저렇게 하니까 아슬해서" 피드백
   으로 추가된 저장 확인 표시(toggleSavedMsg)에 적용. */
.toggle-saved-msg { color: var(--green); font-size: 14px; font-weight: 600; }
/* 이 기기 프린터 고르기 (2026-09-29) — 손가락으로 누르기 좋은 크기. */
.printer-pick { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; white-space: nowrap; }
/* 「저장을 눌러야 바뀌어요」 같은 짧은 말은 묶음 아래 줄로 — 옆에 붙으면 뜰
   때마다 줄 전체가 밀린다. */
.printer-pick #printerPickMsg { flex-basis: 100%; font-size: 13px; }
.printer-pick select { font-size: 16px; padding: 6px 10px; border-radius: 8px; border: 1px solid var(--line); min-height: 40px; }
.printer-pick-test { min-height: 40px; padding: 0 14px; border-radius: 8px; border: 1px solid var(--line); background: #fff; cursor: pointer; }
.printer-pick-save:disabled { opacity: 0.45; cursor: default; }
/* 골랐는데 아직 안 누른 상태 — 눈에 띄게. */
.printer-pick-save.is-dirty { background: var(--navy); color: #fff; border-color: var(--navy); font-weight: 700; }
.printer-row { display: flex; gap: 8px; margin: 6px 0; flex-wrap: wrap; }
.printer-row .printer-name { flex: 1 1 140px; }
.printer-row .printer-ip { flex: 1 1 140px; }
.printer-row .printer-port { width: 90px; }
.printer-row .printer-del { width: 40px; }

/* 지금 어느 기기가 빌지를 뽑고 있는가. 이 기기면 조용한 회색, 다른
   기기면 눈에 띄게 — 「왜 안 나오지」 를 여기서 끝내야 한다. */
.print-device-note {
  font-size: 13px;
  color: var(--muted);
  /* 기기가 여럿이면 길어진다 — 아래 한 줄을 통째로 쓰고 필요하면 꺾인다. */
  order: 10;
  flex-basis: 100%;
  white-space: normal;
}
.print-device-note.is-elsewhere {
  color: var(--red);
  font-weight: 600;
}
.settings-hint { font-size: 16px; color: var(--muted); margin: -6px 0 14px; }
@media (max-width: 700px) {
  .settings-shell { flex-direction: column; gap: 14px; }
  .settings-nav { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; position: static; width: 100%; gap: 6px; padding-bottom: 4px; }
  .settings-nav-btn { flex: 0 0 auto; width: auto; white-space: nowrap; }
  /* 가로로 눕는 좁은 화면에서는 설명줄까지 넣으면 이름이 안 보인다. */
  .settings-nav-btn .nav-sub { display: none; }
  .settings-search input, .settings-search-results { max-width: none; }
}

/* Role-based UI gating — see applyRoleUI() in admin.js. The server enforces
   these same boundaries independently (requirePermission middleware), so
   this is purely about not showing controls a staff session can't use;
   hiding it client-side isn't the actual security boundary. */
.role-staff .owner-only { display: none !important; }
body:not(.role-staff) .staff-only { display: none !important; }
.perm-no-menuEdit .need-menuEdit { display: none !important; }
.perm-no-tableEdit .need-tableEdit { display: none !important; }
.perm-no-settingsEdit .need-settingsEdit { display: none !important; }
/* VIP 카드 판매가·할인율은 직원 누구나 본다 — 설정 수정 권한이 없으면 보기만(2026-10-03). */
.vip-sale-readonly { display: none; }
.perm-no-settingsEdit .vip-sale-readonly { display: block; }
.perm-no-orderCancel .need-orderCancel { display: none !important; }
.perm-no-reservationManage .need-reservationManage { display: none !important; }
.perm-toggle-row { display: flex !important; align-items: center; justify-content: space-between; gap: 12px; }

/* 주문 받는 시간 (2026-09-10) — 손님이 QR 로 주문할 수 있는 시각.
   위 「영업시간」 칸은 손님에게 보여주는 문구고, 여기가 실제로 막는 규칙이다. */
.order-hours-state {
  /* flex + gap 으로 띄우면 화면에는 떨어져 보이지만 복사하면 두 문장이
     붙어버린다("지금 주문 안 받는 중다시 받는 시각 오늘 11:00"). 그래서
     한 줄의 글로 두고 가운뎃점으로 나눈다 — 좁은 화면에서 자연스럽게
     줄바꿈되는 것도 덤이다. */
  display: block;
  font-size: 16px;
  font-weight: 600;
  padding: 10px 14px;
  border-radius: 10px;
  margin: 0 0 14px;
  background: #eef4ec;
  color: #2f6b3a;
}
.order-hours-state.is-closed { background: #f7ecec; color: #8a1c1c; }
.order-hours-state .oh-state-sub { font-weight: 400; color: var(--muted); }
.oh-ranges { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 10px; }
.oh-range { display: flex; align-items: center; gap: 8px; }
.oh-range input[type="time"] { width: auto; flex: 0 0 auto; margin: 0; }
.oh-range .oh-dash { color: var(--muted); }
.settings-card .oh-range button {
  margin: 0;
  padding: 6px 12px;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line, #ddd);
}
.settings-card .oh-add { align-self: flex-start; margin: 4px 0 16px; padding: 8px 14px; background: transparent; color: var(--navy); border: 1px solid var(--navy); }
.oh-label { display: block; font-size: 16px; color: var(--muted); margin: 0 0 8px; }
/* 요일 — 월요일부터 일요일까지 가로 한 줄.
   고른 요일의 편집기만 그 밑에 열린다
   (2026-09-10 사장님: "월부터 일까지 가로로 한 줄로").

   .settings-card 를 앞에 붙이는 이유: 카드 안의 button 은 기본이 남색
   채움(.settings-card button, 특정도 0-1-1)이라, 클래스 하나짜리 규칙은
   그걸 못 이긴다. 처음엔 안 붙였다가 요일 칸이 전부 남색 버튼으로 나왔다. */
.oh-week-row { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin: 0 0 10px; max-width: 620px; }
.settings-card .oh-week-day {
  display: block; width: 100%; margin: 0; padding: 8px 4px;
  background: #f6f2ea; color: var(--ink); border: 1px solid transparent; border-radius: 10px;
  cursor: pointer; text-align: center; font-family: inherit;
}
.oh-week-day .oh-week-name { display: block; font-size: 15px; font-weight: 700; }
.oh-week-day .oh-week-sub { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; line-height: 1.3; }
.oh-week-day.mode-closed { background: #f7ecec; }
.oh-week-day.mode-closed .oh-week-name, .oh-week-day.mode-closed .oh-week-sub { color: #8a1c1c; }
.oh-week-day.mode-custom { background: #eef2f8; }
.oh-week-day.selected { border-color: var(--navy); }

/* 고른 요일 / 고른 날짜의 편집기 */
.oh-panel { background: #faf7f1; border-radius: 10px; padding: 12px 14px; margin: 0 0 16px; max-width: 620px; }
.oh-panel-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.oh-panel-head b { font-size: 16px; color: var(--ink); }
.oh-panel-head select { width: auto; min-width: 150px; margin: 0; }
.oh-panel .oh-note { display: block; margin: 0 0 10px; }
.oh-panel .oh-note span { display: block; font-size: 14px; color: var(--muted); }
.oh-panel .oh-note input { margin-top: 4px; }
.oh-panel-ranges:empty { display: none; }
.oh-panel-ranges .oh-range { margin-bottom: 6px; }

/* 특정 날짜 — 달력. 태풍 휴무처럼 요일 규칙으로는 못 적는 하루짜리 사정. */
.oh-cal { max-width: 620px; margin: 0 0 12px; }
.oh-cal-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.oh-cal-title { font-size: 16px; font-weight: 700; color: var(--ink); }
.settings-card .oh-cal-nav {
  margin: 0; padding: 4px 14px; background: transparent; color: var(--ink);
  border: 1px solid var(--line, #ddd); border-radius: 8px; font-size: 18px; line-height: 1.2;
}
.oh-cal-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 4px; }
.oh-cal-weekdays span { text-align: center; font-size: 12px; color: var(--muted); }
.oh-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.settings-card .oh-cal-day {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 100%; margin: 0; padding: 6px 0 4px; min-height: 44px;
  background: #fff; color: var(--ink); border: 1px solid #ece7df; border-radius: 8px;
  cursor: pointer; font-family: inherit;
}
.oh-cal-day .oh-cal-num { font-size: 15px; font-weight: 600; }
.oh-cal-day .oh-cal-mark { font-size: 11px; line-height: 1.2; min-height: 13px; color: var(--muted); }
/* 요일 규칙으로 이미 쉬는 날 — 흐리게만. 그 날을 따로 찍은 것과 구분돼야 한다. */
.oh-cal-day.weekday-closed { background: #f7f5f2; color: var(--muted); }
.oh-cal-day.mode-closed { background: #f7ecec; border-color: #e6cfcf; }
.oh-cal-day.mode-closed .oh-cal-num, .oh-cal-day.mode-closed .oh-cal-mark { color: #8a1c1c; font-weight: 700; }
.oh-cal-day.mode-custom { background: #eef2f8; border-color: #d6dfea; }
.oh-cal-day.mode-custom .oh-cal-mark { color: var(--navy); font-weight: 700; }
.oh-cal-day.is-today { box-shadow: inset 0 0 0 2px var(--navy); }
.oh-cal-day.is-past { opacity: 0.55; }
.oh-cal-day.selected { border-color: var(--navy); border-width: 2px; }
@media (max-width: 700px) {
  .oh-week-day .oh-week-sub { font-size: 10px; }
}
.perm-toggle-row input[type="checkbox"] { width: auto; margin-top: 0; transform: scale(1.3); }
/* Live "실제 코드 UI" previews next to the logo/cover-photo uploads — shows
   exactly how the upload will render for a customer, not a raw thumbnail. */
.preview-row { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.preview-row > div:first-child { flex: 1; min-width: 180px; }
.live-preview-box { width: 160px; flex-shrink: 0; }
.live-preview-label { font-size: 14px; color: var(--muted); margin-bottom: 6px; }
.logo-qr-preview { width: 140px; height: 140px; border: 1px solid var(--line); border-radius: 10px; background: #fff; display: block; }

/* Real-scale replica of the actual customer order-page header (exact same
   px values as public/css/main.css .hero/.store-header/.table-badge) at
   real phone width — not a shrunk-down thumbnail — so the owner sees
   precisely how the uploaded cover photo will look on a customer's phone. */
.phone-preview-wrap { display: flex; justify-content: center; margin-top: 14px; }
.phone-preview {
  width: 375px; max-width: 100%; border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden; background: #fff; box-shadow: 0 2px 14px rgba(0,0,0,0.08);
}
.phone-hero {
  width: 100%; height: 180px; background: linear-gradient(135deg, #2b2320, #1a1512);
  background-size: cover; background-position: center;
}
.phone-store-header {
  display: flex; align-items: flex-end; gap: 12px; padding: 0 16px 12px; margin-top: -28px; position: relative;
}
.phone-avatar {
  width: 64px; height: 64px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  border: 4px solid #fff; flex-shrink: 0;
  /* overflow visible on purpose — see .store-avatar in main.css, this is
     just the settings-page live preview of that same header. */
}
.phone-avatar img {
  width: 92px; height: 92px; display: block;
  filter: drop-shadow(0 3px 6px rgba(26, 18, 11, 0.35));
}
.phone-store-text { flex: 1; min-width: 0; padding-top: 34px; }
.phone-store-name { font-size: 25px; font-weight: 900; margin: 0 0 4px; color: var(--ink); }
.phone-table-badge {
  display: inline-block; background: var(--red); color: #fff; padding: 4px 11px;
  border-radius: 999px; font-size: 16px; font-weight: 700;
}
.notice-preview-frame { padding: 16px 0; }
.notice-preview-banner {
  margin: 0 16px 0; background: var(--ink); color: #fff; padding: 10px 14px;
  border-radius: 10px; font-size: 16px; line-height: 1.5;
}

/* Admin-panel-wide font size control (settings > 일반) — see
   applyUiFontScale()/setUiFontScale() in admin.js. A simple −/100%/+
   stepper, not a slider, so it matches the small discrete steps the JS
   actually applies (10% per click). */
.ui-font-scale-row { display: flex; align-items: center; gap: 12px; }
.ui-font-scale-btn {
  width: 44px; height: 44px; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; color: var(--ink); font-size: 22px; font-weight: 700;
  cursor: pointer; display: flex; align-items: center; justify-content: center; line-height: 1;
}
.ui-font-scale-btn:hover { background: #f3f3f3; }
.ui-font-scale-value { min-width: 56px; text-align: center; font-size: 18px; font-weight: 700; }
.ui-font-scale-reset {
  margin-left: auto; padding: 8px 14px; border: 1px solid var(--line); background: #fff;
  color: var(--muted); border-radius: 8px; cursor: pointer; font-weight: 700; font-size: 14px;
}
.ui-font-scale-reset:hover { background: #f3f3f3; }

/* 주문 알림음 (설정 > 화면 · 소리) — playAlarm()/ALARM_SOUNDS in admin.js.
   벨소리는 라디오 버튼이지만 동그라미를 숨기고 알약 모양으로 보여준다.
   홀에서 장갑 낀 손으로도 누르는 자리라 터치 면적을 넉넉히 잡았다. */
.alarm-field-label {
  font-weight: 700; font-size: 15px; color: var(--ink);
  margin: 14px 0 8px;
}
.alarm-tone-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.alarm-tone {
  display: inline-flex; align-items: center; margin: 0 !important;
  padding: 10px 16px; border: 1px solid var(--line); border-radius: 999px;
  background: #fff; color: var(--ink); font-size: 15px; font-weight: 600;
  cursor: pointer; user-select: none; min-height: 44px;
}
.alarm-tone input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; margin: 0; }
.alarm-tone:hover { background: #f3f3f3; }
.alarm-tone.is-on {
  background: var(--red); border-color: var(--red); color: #fff;
}
/* ▶ 는 벨소리 알약에만 붙인다. 횟수 알약에 붙으면 "▶세 번" 이 되어
   "세 번을 재생" 처럼 읽힌다 — 고른 값이라는 뜻이 흐려진다. */
.alarm-tone-grid:not(.alarm-repeat-grid) .alarm-tone.is-on::before { content: "▶ "; font-size: 12px; }
/* 긴 벨소리는 곡 길이를 알약 안에 같이 적는다 — 고르기 전에 "이게 몇 초짜리
   인가" 를 알아야 한다. 미리듣기로 하나씩 재보게 만들 일이 아니다. */
.alarm-tone-len {
  font-style: normal; font-size: 12px; font-weight: 600; margin-left: 7px;
  opacity: 0.6;
}
.alarm-tone.is-on .alarm-tone-len { opacity: 0.85; }
/* 반복 횟수 줄. 긴 벨소리를 고르면 통째로 숨는다(hidden). */
.alarm-repeat-row { margin: 0; }

.alarm-volume-row { display: flex; align-items: center; gap: 14px; }
.alarm-volume-row input[type="range"] {
  flex: 1; min-width: 200px; margin: 0; height: 32px; accent-color: var(--red); cursor: pointer;
}
.alarm-volume-value {
  min-width: 72px; text-align: right; font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.alarm-volume-marks {
  display: flex; justify-content: space-between; margin: 2px 86px 0 0;
  font-size: 13px; color: var(--muted);
}
.alarm-actions { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
.alarm-preview-btn {
  padding: 12px 20px; border: 1px solid var(--line); border-radius: 10px;
  background: #fff; color: var(--ink); font-size: 16px; font-weight: 700; cursor: pointer;
  min-height: 44px;
}
.alarm-preview-btn:hover { background: #f3f3f3; }
.alarm-preview-btn:active { transform: translateY(1px); }
.alarm-reset-btn {
  padding: 12px 18px; border: 1px solid var(--line); border-radius: 10px;
  background: #fff; color: var(--muted); font-size: 15px; font-weight: 700; cursor: pointer;
  min-height: 44px;
}
.alarm-reset-btn:hover { background: #f3f3f3; }

/* 알림이 울리는 동안만 뜨는 정지 버튼 (실시간 주문 화면 위쪽).
   울리는 것 자체가 급한 일이라 눈에 띄어야 하고, 그래서 주변 도구 버튼들과
   달리 채워진 색으로 둔다. 깜빡임은 prefers-reduced-motion 에서 멈춘다. */
.alarm-stop-btn {
  padding: 8px 16px; border: 1px solid var(--red); border-radius: 999px;
  background: var(--red); color: #fff; font-size: 15px; font-weight: 700;
  cursor: pointer; min-height: 40px; animation: alarm-stop-pulse 1s ease-in-out infinite;
}
.alarm-stop-btn:hover { filter: brightness(1.08); }
@keyframes alarm-stop-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(181, 35, 44, 0.5); }
  50% { box-shadow: 0 0 0 7px rgba(181, 35, 44, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .alarm-stop-btn { animation: none; }
}
.alarm-saved-msg { margin: 0 !important; }
.alarm-note { margin: 12px 0 0 !important; }
.alarm-loud-warn { color: var(--orange); }

/* Per-component kitchen-ticket font size editor (settings > 관리자 전용) —
   fields on the left, an actual-size (1x, not zoomed) live preview of the
   real ticket HTML on the right, same "실제 크기" idea as .phone-preview-wrap
   above. See updateTicketFontPreview() in admin.js. */
.ticket-font-editor { display: flex; gap: 24px; flex-wrap: wrap; align-items: flex-start; margin: 4px 0 16px; }
.ticket-font-fields { display: flex; flex-direction: column; gap: 10px; flex: 1; min-width: 260px; }
.ticket-font-field { display: flex !important; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 0 !important; }
.ticket-font-field span { flex: 1; font-size: 15px; }
.ticket-font-field input {
  width: 64px; flex: none; margin-top: 0; text-align: center; font-size: 16px;
}
.ticket-font-field-header { padding-bottom: 2px; }
/* .ticket-font-field span already sets flex:1/font-size:15px with the same
   specificity (one class + one element each); qualifying with the parent
   class here (two classes) is what lets these actually win over that rule. */
.ticket-font-field-header .ticket-font-col-label { flex: none; width: 64px; text-align: center; font-size: 13px; color: var(--muted); font-weight: 700; }
.ticket-font-preview-wrap {
  flex-shrink: 0; background: #dfe3e7; border-radius: 10px; padding: 16px;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.ticket-font-preview-frame {
  width: 302px; height: 440px; border: none; background: #fff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
}
/* 사장님 피드백(2026-09-08): "금액 나오는 걸로 미리보기 보면서 따로
   설정할 수 있게 해달라는 의미였어" — 주방용/결제용(금액) 두 사본을
   한 좁은 iframe 안에 이어붙여 스크롤해야 보이게 하는 대신(스크롤이
   있는 줄 모르고 못 볼 수 있음), 탭처럼 전환하는 버튼 두 개를 두고
   현재 선택된 쪽만 실제 크기로 또렷하게 보여준다. see admin.js
   ticketFontPreviewMode/updateTicketFontPreview(). */
.ticket-font-preview-toggle { display: flex; gap: 6px; }
.ticket-font-preview-toggle button {
  padding: 5px 12px; border-radius: 999px; border: 1.5px solid var(--line, #d8dbe0);
  background: #fff; color: var(--muted, #667); font-size: 13px; font-weight: 700; cursor: pointer;
}
.ticket-font-preview-toggle button.active { background: #1f2430; border-color: #1f2430; color: #fff; }
.notice-preview-banner:empty { display: none; }
.notice-preview-empty { text-align: center; margin: 0 16px; }

/* Settlement (결산) — wider, dashboard-style layout (1100px vs the 640px
   settings cards) since charts and tables benefit from the extra room. */
/* 지난 정산 기록을 오른쪽 콘텐츠와 나란히 놓는 왼쪽 탭 sidebar — 예전엔
   이 날짜 목록이 페이지 맨 아래에 있어서 날짜를 클릭해도 위쪽 요약
   카드가 바뀌는 게 화면 밖이라 안 보였음 (2026-09 피드백: "누르고
   위에가 바뀌는 것도 안보이고 위 아래 왔다갔다 하는 거 별로야 ...
   왼쪽 탭 느낌으로"). .settings-shell/.settings-nav와 같은 뼈대 —
   sidebar가 sticky로 붙어 있고 옆의 콘텐츠만 갱신되니 스크롤 위치가
   그대로 유지된다. */
.settlement-shell { display: flex; align-items: flex-start; gap: 24px; }
.settlement-nav {
  display: flex; flex-direction: column; gap: 2px; flex: 0 0 220px;
  position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto;
  background: #fff; border-radius: 14px; padding: 10px; box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.settlement-content { flex: 1; min-width: 0; }
@media (max-width: 1100px) {
  .settlement-shell { flex-direction: column; }
  .settlement-nav { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; position: static; width: 100%; max-height: none; }
}
.settlement-toolbar {
  display: flex; align-items: center; gap: 10px; max-width: 1560px; margin: 0 auto 20px; flex-wrap: wrap;
  background: #fff; border-radius: 12px; padding: 14px 18px; box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.settlement-date-label { display: flex; align-items: center; gap: 8px; font-size: 17px; color: var(--muted); }
.settlement-date-label input[type="date"] { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 18px; }
.settlement-date-sep { color: var(--muted); }
.settlement-toolbar button {
  padding: 9px 16px; border: 1px solid var(--line); border-radius: 8px; background: #fff;
  color: var(--ink); font-weight: 700; cursor: pointer; font-size: 17px;
}
.settlement-toolbar #settlementTodayBtn,
.settlement-toolbar #settlementWeekBtn,
.settlement-toolbar #settlementMonthBtn { background: var(--cream); }
.settlement-toolbar .settlement-close-btn { margin-left: auto; background: var(--navy); border-color: var(--navy); color: #fff; }
.settlement-toolbar .settlement-close-btn:disabled { background: var(--line); border-color: var(--line); color: var(--muted); cursor: not-allowed; }
/* 직원 세션의 결산 툴바 — 날짜 고르는 칸이 전부 숨겨진 자리에 「무엇을
   보고 있는지」 한 줄만 남는다 (admin.js renderSettlement, data.today_only). */
/* 전체 메뉴 — 많이 팔린 순, 좌에서 우로 뻗는 막대 (2026-09-11 사장님 요청).
   높이를 못 박고 그 안에서 굴린다. 51줄을 그대로 펼치면 결산 화면이 다시
   길어져서, 이 화면을 갈아엎은 이유로 도로 돌아간다. */
.stl-allmenu-head { font-size: 16px; color: var(--muted); margin-bottom: 10px; }
/* 여기도 막대 시작을 맞춘다 — 위 .stl-bars 주석과 같은 이유. */
.stl-allmenu {
  max-height: 520px; overflow-y: auto; padding-right: 6px;
  display: grid; grid-template-columns: minmax(120px, 230px) minmax(0, 1fr) 64px;
  align-items: center; column-gap: 12px; row-gap: 10px;
}
.stl-menu-row { display: contents; }
.stl-menu-name {
  font-size: 16px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stl-menu-track { display: block; height: 12px; background: #efeae1; border-radius: 999px; overflow: hidden; }
.stl-menu-fill { display: block; height: 100%; background: var(--navy); border-radius: 999px; min-width: 3px; }
.stl-menu-qty { font-size: 16px; font-weight: 700; text-align: right; }
/* 한 개도 안 나간 줄. 흐리게 두되 지우지는 않는다 — 스크롤을 내리면
   여기부터가 「안 팔린 애들」이다. */
.stl-menu-row.is-zero .stl-menu-name,
.stl-menu-row.is-zero .stl-menu-qty { color: var(--muted); }
.stl-menu-soldout {
  font-size: 12px; font-weight: 700; color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px; padding: 1px 6px; margin-left: 6px;
}
@media (max-width: 700px) {
  .stl-allmenu { grid-template-columns: minmax(90px, 140px) minmax(0, 1fr) 52px; column-gap: 8px; }
  .stl-menu-name, .stl-menu-qty { font-size: 15px; }
}

/* 메뉴별 추이 — 고르는 줄 */
.stl-item-trend-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 8px; }
.stl-item-trend-bar label { font-size: 16px; color: var(--muted); }
.stl-item-trend-bar select {
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
  font-size: 16px; font-family: inherit; background: #fff; color: var(--ink); max-width: 340px;
}
.stl-item-trend-total { font-size: 16px; font-weight: 700; }

/* 판매 비중 — 입체 원 그래프 + 범례. 숫자는 그림이 아니라 범례에서 읽는다
   (admin.js drawPie3d 주석). */
.stl-pie-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; }
.stl-pie-canvas { flex: 0 0 auto; }
.stl-pie-legend { flex: 1 1 260px; min-width: 240px; }
.stl-pie-item {
  display: grid; grid-template-columns: 22px 14px minmax(0, 1fr) 58px 46px;
  align-items: center; gap: 8px; padding: 3px 0; font-size: 16px; break-inside: avoid;
}
.stl-pie-rank { text-align: right; font-size: 13px; color: var(--muted); }
/* 전 메뉴를 적으면 50줄이 넘는다(2026-09-30 「기타」 없앰) — 한 줄로 길게 늘이지
   않고 폭이 되는 만큼 여러 단으로 나눈다. */
.stl-pie-legend.is-long { flex-basis: 100%; column-width: 280px; column-gap: 28px; }
.stl-pie-swatch { width: 14px; height: 14px; border-radius: 4px; display: block; }
.stl-pie-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stl-pie-qty { text-align: right; font-weight: 700; }
.stl-pie-pct { text-align: right; color: var(--muted); }

.settlement-today-only {
  font-size: 17px; font-weight: 700; color: var(--ink);
  display: inline-flex; align-items: center; gap: 8px;
}
/* 정산 기록 사이드바가 없는 직원 화면에서는 본문이 가로를 다 쓴다. */
.role-staff .settlement-shell { display: block; }

.settlement-summary-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; max-width: 1560px; margin: 0 auto 20px; }
.settlement-card {
  background: #fff; border-radius: 14px; padding: 18px 20px; box-shadow: 0 1px 4px rgba(0,0,0,0.06);
  border-top: 3px solid var(--navy);
}
.settlement-card-label { font-size: 16px; color: var(--muted); margin-bottom: 8px; }
.settlement-card-value { font-size: 36px; font-weight: 800; color: var(--ink); }
.settlement-card-warn { border-top-color: #d99a94; }
.settlement-card-warn.has-problems { background: #fdecea; border-top-color: #b3261e; }
.settlement-card-warn.has-problems .settlement-card-value { color: #b3261e; }

.settlement-wide-card { max-width: 1560px; margin: 0 auto 20px; background: #fff; border-radius: 14px; padding: 22px 24px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.settlement-wide-card h3 { margin-top: 0; }
.settlement-card-problem-block { border-left: 4px solid #b3261e; }
.settlement-problem-row { border: 1px solid #f3c8c4; background: #fff8f7; border-radius: 10px; padding: 10px 14px; margin-bottom: 8px; }
.settlement-problem-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; font-size: 17px; font-weight: 700; }
.settlement-problem-time { color: var(--ink); }
.settlement-problem-table { color: var(--navy); }
.settlement-problem-status { color: #b3261e; }
.settlement-problem-total { margin-left: auto; }
.settlement-problem-items { font-size: 16px; color: var(--muted); margin-top: 4px; }
.settlement-items-table { width: 100%; border-collapse: collapse; font-size: 17px; }
.settlement-items-table th, .settlement-items-table td { text-align: left; padding: 8px 6px; border-bottom: 1px solid var(--line); }
.settlement-items-table th { color: var(--muted); font-weight: 600; font-size: 16px; }
/* 지난 정산 기록 — lives inside .settlement-nav now (the 왼쪽 탭 sidebar
   above), grouped into one <details> "folder" per year-month (see
   fmtHistoryMonthLabel()/loadSettlementHistory() in admin.js) so browsing
   months of history means opening the month you want rather than scrolling
   past every day ever saved (owner: "파일 폴더처럼 날짜별로 들어가서 볼
   수 있게 해줬으면 좋겠어"). Each day is a compact two-line button — date
   on top, revenue (and a ⚠ warn count when relevant) below — sized for the
   narrow sidebar rather than the wide flat rows this used to be. */
.settlement-history-month { }
.settlement-history-month-summary {
  padding: 8px 8px; cursor: pointer; font-weight: 700; font-size: 15px; border-radius: 8px;
  list-style: none;
}
.settlement-history-month-summary::-webkit-details-marker { display: none; }
.settlement-history-month-summary:hover { background: #f0f0f0; }
.settlement-history-month-days { display: flex; flex-direction: column; gap: 2px; padding: 2px 0 6px 4px; }
.settlement-history-row {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%;
  text-align: left; background: none; border: none; border-radius: 8px;
  padding: 6px 10px; cursor: pointer; font: inherit; color: var(--ink);
}
.settlement-history-row:hover { background: #f0f0f0; }
.settlement-history-row.active { background: var(--navy); color: #fff; }
.settlement-history-row.active .settlement-history-row-sub { color: rgba(255, 255, 255, 0.8); }
.settlement-history-row.active .settlement-history-warn { color: #ffd7d3; }
.settlement-history-date { font-weight: 700; font-size: 14px; }
.settlement-history-row-sub { font-size: 12px; color: var(--muted); }
.settlement-history-warn { color: #b3261e; font-weight: 700; }

.settlement-charts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1560px; margin: 0 auto 20px; }
.settlement-charts-grid .settlement-wide-card { margin: 0; max-width: none; }
@media (max-width: 860px) { .settlement-charts-grid { grid-template-columns: 1fr; } }
.settlement-chart-wrap { position: relative; width: 100%; height: 260px; margin-bottom: 16px; overflow: hidden; }
.settlement-chart-wrap canvas { position: absolute; top: 0; left: 0; width: 100% !important; height: 100% !important; }
/* 그래프를 못 그렸을 때 그 자리에 뜨는 말. 빈 그래프는 「오늘 손님이
   없었나 보다」로 읽힌다 — 못 그렸으면 못 그렸다고 적어야 한다. */
.stl-chart-missing {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0 24px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: #8a8f9c;
  background: #fafafa;
  border: 1px dashed #d8dbe3;
  border-radius: 10px;
}

/* Modal */
/* 창의 높이를 **실제로 보이는 높이**로 잰다.
 *
 * 2026-09-16 사장님(태블릿 스크린샷과 함께): "이것도 여전히 짤리고."
 * 주문이 많은 자리를 열면 「미결제 합계 · 결제 완료」 줄이 화면 아래로
 * 넘어가 아예 안 보였다.
 *
 * 원인은 vh 다. 태블릿 브라우저에서 100vh 는 **주소창을 뺀 높이가 아니라
 * 주소창까지 포함한 큰 쪽**이다(large viewport). 그래서 90vh 로 잡아둔
 * 창이 실제로 보이는 영역보다 길어지고, 맨 아래 줄이 주소창 뒤로 숨는다.
 * 데스크톱 브라우저에는 그 차이가 없어서 여기서는 멀쩡해 보인다 — 실제로
 * 그래서 못 잡았다.
 *
 * dvh 는 지금 보이는 높이다. 옛 브라우저를 위해 vh 를 먼저 적고 dvh 로
 * 덮는다 — dvh 를 모르는 브라우저는 그 줄을 무시하고 vh 를 쓴다. */
.modal-backdrop {
  position: fixed;
  inset: 0;
  height: 100vh;
  height: 100dvh;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  /* 창은 무엇보다 위에 있어야 한다.
   *
   * 2026-09-16 사장님: "펼치면 저 위에가 x 가 없어지고 잘리는 것 같아."
   * 목록을 펼치면 창이 길어져 위로 올라가는데, 테스터 모드 띠(z-index: 60)와
   * 위쪽 메뉴 바(30)가 그 위를 덮어서 **닫기(✕) 버튼이 가려졌다.** 창을 못
   * 닫는 것은 갇히는 것이다. 띠는 「켜둔 것을 잊지 말라」고 있는 것이지
   * 창을 가리라고 있는 것이 아니다. */
  z-index: 100;
  padding: 20px;
}
.modal {
  background: #fff;
  border-radius: 14px;
  padding: 22px;
  width: 100%;
  max-width: 560px;
  max-height: 90vh;
  max-height: 90dvh;
  /* flex 자식의 자동 최소 높이가 max-height 를 이겨서 창이 넘치는 일을 막는다. */
  min-height: 0;
  overflow-y: auto;
  position: relative;
}
.modal-close { position: absolute; right: 14px; top: 14px; border: none; background: #f1ede6; width: 30px; height: 30px; border-radius: 999px; cursor: pointer; }
.modal-form label { display: block; font-size: 16px; color: var(--muted); margin-bottom: 12px; }
.modal-form input, .modal-form select { width: 100%; padding: 9px; border: 1px solid var(--line); border-radius: 8px; margin-top: 4px; font-size: 18px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
.form-row.checkboxes { grid-template-columns: repeat(3, auto); align-items: center; gap: 16px; }
.form-row.checkboxes label { display: flex; align-items: center; gap: 6px; font-size: 17px; color: var(--ink); }
.form-row.checkboxes input { width: auto; margin: 0; }
.photo-preview { width: 120px; height: 120px; object-fit: cover; border-radius: 10px; margin-bottom: 12px; }
.allergen-checkboxes { display: flex; flex-wrap: wrap; gap: 8px 14px; margin: 0 0 16px; padding: 10px 12px; background: #f8f5ef; border-radius: 10px; }
.allergen-checkbox { display: flex !important; align-items: center; gap: 5px; font-size: 17px; color: var(--ink); width: auto; margin: 0 !important; }
.allergen-checkbox input { width: auto; margin: 0; }
.modal-actions { display: flex; justify-content: space-between; margin-top: 10px; }

/* 빌지 미리보기 창 — 실시간 주문 카드의 「👁️ 미리보기」.

   영수증은 좁고 긴 종이라 창도 그 비율로 둔다. 기본 .modal 의 560px 는
   빌지가 가운데에 뜨고 양옆이 휑하다.

   높이를 dvh 로도 적는 이유는 .modal-backdrop 과 같다 — 태블릿에서 주소창이
   접혔다 펴지면 vh 가 실제 보이는 높이보다 커져서 창 아래가 잘린다.
   제목·설명이 위에 있으므로 58% 로 둔다. 여기서 100% 를 주면 창이 화면을
   넘겨 ✕ 가 밖으로 나간다 — 창을 못 닫는 것은 갇히는 것이다. */
.modal.ticket-preview-modal { max-width: 460px; }
.ticket-preview-modal h2 { margin: 0 34px 4px 0; font-size: 20px; }
.ticket-preview-modal .settings-hint { margin: 0 0 12px; }
#ticketPreviewFrame {
  display: block;
  width: 100%;
  height: 58vh;
  height: 58dvh;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
}

/* 메뉴 수정 폼의 왼쪽 탭 — 사장님(2026-09-10): "메뉴 관리 폼이 너무 이것
   저것 다 섞여 있어서 엄청 헷갈려 ... 왼쪽에 탭을 둬서 설정처럼 구분하면서
   보는 게 좋을 것 같아". .settings-shell/.settings-nav 와 같은 뼈대다.
   폼이 넓어져야 왼쪽 탭과 오른쪽 입력칸이 같이 들어가므로 이 창만 넓힌다. */
.modal.modal-wide { max-width: 880px; }

/* 창 크기를 **한 크기로 고정한다.**

   사장님(2026-09-10): "메뉴 창이 크기에 따라 흰색 창이 번쩍번쩍 바뀌는데
   그거 고정으로 해서 너무 크면 공백 그대로 냅두고 작으면 스크롤 내릴 수
   있게 해줘. 공통 크기로."

   탭마다 내용의 길이가 달랐다 — 「기본」은 짧고 「옵션」은 길다. 창이
   내용에 맞춰 늘었다 줄었다 하니, 탭을 옮길 때마다 흰 상자가 튀었다.
   .item-form-pane 에 min-height 로 바닥을 깔아 뒀었지만 그건 짧은 쪽만
   막을 뿐, 긴 쪽이 넘칠 때는 여전히 창이 커졌다.

   그래서 창의 키를 아예 못 박는다.

     - 짧은 탭 → 아래가 그냥 빈다. 창은 안 움직인다.
     - 긴 탭  → 오른쪽 내용만 굴러간다. 창도, 왼쪽 탭도, 저장 버튼도
                제자리에 있다.

   예전에는 창 전체가 굴렀다. 그래서 「옵션」 탭에서 아래로 내리면 저장
   버튼이 화면 밖으로 사라졌다 — 저장하려고 다시 올라와야 했다. */
.modal.modal-wide {
  height: min(86vh, 780px);
  height: min(86dvh, 780px);
  max-height: none;   /* 위의 .modal 이 걸어둔 90vh 를 대신한다 */
  overflow: hidden;   /* 굴리는 것은 아래 .item-form-content 한 곳뿐이다 */
  display: flex;
  flex-direction: column;
}
/* 제목과 저장 줄은 안 굴러간다. min-height:0 이 있어야 가운데가 줄어든다
   — flex 자식은 기본적으로 내용보다 작아지지 않아서, 이게 없으면 창이
   내용만큼 늘어나 고정한 의미가 없어진다. */
.modal.modal-wide > h2 { flex: 0 0 auto; margin-top: 0; }
.modal.modal-wide > .modal-form {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.modal.modal-wide .item-form-shell { flex: 1 1 auto; min-height: 0; }
.modal.modal-wide .item-form-nav { align-self: stretch; }
.modal.modal-wide .item-form-content {
  height: 100%;
  overflow-y: auto;
  /* 굴림대가 입력칸 테두리를 덮지 않게 한 뼘 띄운다. */
  padding-right: 8px;
}
/* 굴러가는 내용과 저장 줄 사이에 실선을 하나 둔다. 없으면 내용이 버튼
   뒤로 잘려 들어가는 것처럼 보여서, 「화면이 깨졌나」로 읽힌다. */
.modal.modal-wide .modal-actions {
  flex: 0 0 auto;
  border-top: 1px solid var(--line);
  padding-top: 14px;
  margin-top: 14px;
}
.item-form-shell { display: flex; align-items: flex-start; gap: 20px; }
.item-form-nav { display: flex; flex-direction: column; gap: 4px; flex: 0 0 168px; }
.item-form-nav-btn {
  display: block; width: 100%;
  background: transparent; border: none; text-align: left; color: var(--muted);
  padding: 9px 12px; border-radius: 8px; cursor: pointer; font-size: 16px; font-weight: 600;
  font-family: inherit;
}
.item-form-nav-btn:hover { background: #f0f0f0; }
.item-form-nav-btn.active { background: var(--navy); color: #fff; }
.item-form-nav-btn .nav-name { display: block; }
/* 이름만으로는 「가격 비고」가 가격에 있는지 손님 화면에 있는지 알 수 없다. */
.item-form-nav-btn .nav-sub { display: block; font-size: 13px; font-weight: 400; opacity: 0.72; margin-top: 2px; }
.item-form-nav-btn.active .nav-sub { opacity: 0.78; }
.item-form-content { flex: 1; min-width: 0; }
/* 창 자체가 고정 크기라(위 .modal.modal-wide) 여기에 바닥을 깔 필요가
   없다. 오히려 깔아두면 짧은 탭에서도 굴림대가 생긴다. */
.item-form-pane { min-height: 0; }
/* 체크박스 줄은 원래 3칸 격자였다 — 탭으로 나누면서 한 줄에 한두 개만
   남는 탭이 생겨, 「매운맛」과 「대표 메뉴」가 화면 양끝으로 벌어졌다.
   개수와 상관없이 왼쪽부터 나란히 붙게 한다. */
.item-form-pane .form-row.checkboxes { display: flex; flex-wrap: wrap; gap: 10px 20px; }

/* 옵션 칩 입력 — 사장님(2026-09-10): "옵션 치고 엔터하면 밑에 글자
   등록되어있는 것처럼 뜨게 해서 보다 더 직관적으로 옵션이 등록되었다는 걸
   인지하게 해주고 싶어." 진짜 값은 옆의 hidden 입력이 쉼표로 들고 있고,
   여기는 그걸 보여주고 고치는 화면일 뿐이다. */
.chip-field {
  border: 1px solid var(--line); border-radius: 10px; padding: 8px; margin: 4px 0 12px;
  background: #fff; cursor: text;
}
.chip-list { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.chip-list[hidden] { display: none; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--cream); border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 6px 5px 12px; font-size: 16px; color: var(--ink); max-width: 100%;
}
.chip-text { overflow-wrap: anywhere; }
/* 옵션 값은 이름과 다른 칸이다 — 이름이 「100元」처럼 금액 모양이어도
   어디까지가 이름이고 어디가 받을 돈인지 한눈에 갈린다. */
.chip-price {
  background: var(--navy); color: #fff; border-radius: 999px;
  padding: 2px 10px; font-size: 14px; font-weight: 700; white-space: nowrap;
}
.chip-x {
  border: none; background: rgba(0,0,0,0.08); color: var(--ink);
  width: 20px; height: 20px; border-radius: 999px; cursor: pointer; line-height: 1;
  font-size: 12px; flex-shrink: 0; padding: 0;
}
.chip-x:hover { background: var(--red); color: #fff; }
/* 입력칸은 테두리를 지운다 — 조각들과 같은 상자 안에 있는 것처럼 보이게. */
.modal-form .chip-field input.chip-entry,
.modal-form .chip-field input.chip-entry-price {
  border: none; margin: 0; padding: 6px 4px; font-size: 17px; background: transparent;
}
.modal-form .chip-field input.chip-entry:focus,
.modal-form .chip-field input.chip-entry-price:focus { outline: none; }
/* 값이 붙는 「추가 옵션」만 이름·가격 두 칸이다. */
.chip-entry-row { display: flex; align-items: center; gap: 8px; }
.modal-form .chip-entry-row input.chip-entry { flex: 1; min-width: 0; }
.modal-form .chip-entry-row input.chip-entry-price { flex: 0 0 90px; text-align: right; }
.chip-add-btn {
  flex: 0 0 auto; border: 1px solid var(--line); background: var(--cream); color: var(--ink);
  border-radius: 8px; padding: 7px 14px; font-size: 16px; font-weight: 700; cursor: pointer;
  font-family: inherit;
}
.chip-add-btn:hover { background: var(--navy); border-color: var(--navy); color: #fff; }

/* 「하나만 고르는 것」과 「여러 개 고를 수 있는 것」의 경계. 손님 화면에서는
   실제로 다르게 동작하는데(버튼 하나 vs 체크박스) 폼에서는 넷이 똑같이
   생겨서 구분할 방법이 없었다. */
.option-group-title {
  margin: 4px 0 2px; font-size: 17px; font-weight: 800; color: var(--ink);
}
.option-group-title-multi {
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line);
}
.option-group-hint { margin: 0 0 14px; font-size: 15px; color: var(--muted); line-height: 1.5; }

/* 태블릿 세로처럼 좁은 화면에서는 왼쪽 탭이 들어갈 자리가 없다 — 설정
   화면과 같이 위쪽 가로 줄로 눕힌다. */
@media (max-width: 760px) {
  .item-form-shell { flex-direction: column; gap: 12px; }
  .item-form-nav { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; width: 100%; gap: 6px; padding-bottom: 4px; }
  .item-form-nav-btn { flex: 0 0 auto; width: auto; white-space: nowrap; }
  .item-form-nav-btn .nav-sub { display: none; }
  /* 가로로 누운 탭 줄은 눌리면 안 된다. 안 그러면 좁은 화면에서 탭이
     찌그러지고 아래 내용이 그만큼 더 길어진다. */
  .modal.modal-wide .item-form-nav { flex: 0 0 auto; align-self: auto; }
  .modal.modal-wide .item-form-content { height: auto; flex: 1 1 auto; min-height: 0; }
}
.primary-btn { background: var(--red); color: #fff; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-weight: 700; }
.danger-btn { background: #fff; color: var(--red); border: 1px solid var(--red); padding: 10px 20px; border-radius: 8px; cursor: pointer; }

/* LINE token/secret reveal row */
.line-secret-row { display: flex; gap: 8px; align-items: center; }
.line-secret-row input { flex: 1; }
.line-reveal-btn {
  flex-shrink: 0; padding: 8px 12px; font-size: 16px; font-weight: 700; border-radius: 8px;
  border: 1px solid var(--line); background: #fff; color: var(--ink); cursor: pointer;
}

/* LINE pending/approved follower lists */
.line-people-list { display: flex; flex-direction: column; gap: 8px; margin: 8px 0 16px; }
.line-people-empty { font-size: 16px; color: var(--muted); }
.line-person-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--line);
  border-radius: 10px; background: #fafaf8;
}
.line-person-avatar { width: 36px; height: 36px; border-radius: 999px; object-fit: cover; background: var(--line); flex-shrink: 0; }
.line-person-avatar-fallback {
  width: 36px; height: 36px; border-radius: 999px; background: var(--navy); color: #fff; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700;
}
.line-person-name { flex: 1; font-size: 17px; font-weight: 600; }
.line-person-row button { padding: 6px 12px; font-size: 16px; border-radius: 8px; border: none; cursor: pointer; font-weight: 700; }
.line-approve-btn { background: var(--navy); color: #fff; }
.line-reject-btn, .line-remove-btn { background: #fff; color: #b3261e; border: 1px solid #b3261e !important; }

/* Reservations (예약) */
.reservations-list { display: flex; flex-direction: column; gap: 10px; max-width: 900px; }
.reservation-row {
  display: flex; align-items: center; gap: 18px; background: #fff; border-radius: 12px;
  padding: 14px 18px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); cursor: pointer;
}
.reservation-row:hover { background: #f7f5f1; }
.reservation-row.reservation-cancelled { opacity: 0.55; }
.reservation-when { min-width: 90px; text-align: center; }
.reservation-date { font-size: 16px; color: var(--muted); }
.reservation-time { font-size: 23px; font-weight: 800; color: var(--ink); }
.reservation-info { flex: 1; min-width: 0; }
.reservation-name { font-weight: 700; font-size: 18px; }
.reservation-party { font-weight: 500; color: var(--muted); font-size: 16px; }
.reservation-meta { font-size: 16px; color: var(--muted); margin-top: 2px; }
.reservation-status { font-size: 16px; font-weight: 700; padding: 4px 12px; border-radius: 999px; background: #eef1f7; color: var(--navy); }
.reservation-status.status-cancelled { background: #fdecea; color: #b3261e; }

/* 회원(VIP) — physical-card registration list, Admin > 회원(VIP) tab */
.vip-add-card-form { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; max-width: 900px; }
.vip-add-card-form input { padding: 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; font-family: inherit; }
.vip-add-card-form input#vipNewCardNumber { flex: 1 1 160px; }
.vip-add-card-form input#vipNewIssueDate { flex: 0 0 160px; }
.vip-add-card-form input#vipNewDiscount { flex: 0 0 110px; }
.vip-add-card-form input#vipNewNote { flex: 2 1 220px; }
.vip-add-card-form button {
  flex: 0 0 auto; padding: 10px 18px; border: none; background: var(--navy); color: #fff;
  border-radius: 8px; cursor: pointer; font-weight: 700; font-size: 16px;
}
.vip-cards-list { display: flex; flex-direction: column; gap: 10px; max-width: 900px; }
.vip-card-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  background: #fff; border-radius: 12px; padding: 14px 18px; box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.vip-card-main { flex: 1; min-width: 220px; }
.vip-card-number { font-weight: 800; font-size: 19px; letter-spacing: 0.5px; }
.vip-card-meta { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; margin-top: 6px; font-size: 15px; color: var(--muted); }
.vip-card-customer { margin-top: 4px; font-size: 15px; color: var(--ink); }
.vip-card-note { margin-top: 4px; font-size: 14px; color: var(--muted); font-style: italic; }
.vip-badge { font-size: 13px; font-weight: 700; padding: 3px 10px; border-radius: 999px; background: #eef1f7; color: var(--navy); }
.vip-badge.vip-active { background: #e6f4ea; color: var(--green); }
.vip-badge.vip-expired { background: #fdecea; color: var(--red); }
.vip-badge.vip-unclaimed { background: #f0f0f0; color: var(--muted); }
.vip-card-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.vip-card-actions button {
  padding: 7px 14px; font-size: 15px; border-radius: 8px; border: 1px solid var(--line);
  background: #fff; cursor: pointer; font-weight: 700; color: var(--ink);
}
.vip-card-actions button.primary-btn { background: var(--navy); color: #fff; border-color: var(--navy); }
.vip-card-actions button.vip-unlink-btn, .vip-card-actions button.vip-del-btn { color: var(--red); border-color: var(--red); }
.vip-card-edit-form { display: flex; flex-direction: column; gap: 8px; }
.vip-card-edit-form label { font-size: 14px; color: var(--muted); display: flex; flex-direction: column; gap: 3px; }
.vip-card-edit-form input {
  padding: 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 15px; font-family: inherit; width: auto; max-width: 220px;
}

.order-detail-modal { max-width: 420px; }
/* 사장님 피드백(2026-09-06, 태블릿 화면 녹화와 함께): "지금 보면 너비가
   좁아서 양 옆이 꽉 찬게 아니라 잘렸어" — 주문 수정 모달은 위
   .order-detail-modal의 420px 제한을 그대로 쓰기엔 품목 줄(이름/수량/가격/
   삭제)과 옵션 pill, 추가 영역, 안내 문구까지 다 들어가야 해서 태블릿
   화면에서 유독 빽빽하게 눌려 보였다. 읽기 전용 주문 상세 팝업
   (#orderDetailBackdrop, 품목·합계만 보여줘서 좁아도 괜찮음)은 그대로 두고,
   주문 수정 쪽 메인 패널만 기본 .modal 상한(560px)까지 넓힌다 — 추가 항목
   피커 패널(.order-edit-picker-modal, 별도로 폭 고정됨)은 영향받지 않는다. */
#orderEditBackdrop .order-edit-panels > .order-detail-modal:not(.order-edit-picker-modal) {
  max-width: 560px;
}
.add-table-zone-modal { max-width: 420px; }
.add-table-zone-modal h2 { margin: 0 0 4px; }
.table-picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(56px, 1fr)); gap: 8px; margin-top: 14px; }
.table-picker-btn {
  padding: 10px 4px; border: 1px solid var(--line); border-radius: 8px; background: #fff; cursor: pointer;
  font-weight: 700; font-size: 18px; color: var(--ink);
}
.table-picker-btn:hover { border-color: var(--red); color: var(--red); background: #fdf3f2; }
.table-picker-btn.selected { border-color: var(--red); background: var(--red); color: #fff; }
.table-picker-empty { color: var(--muted); font-size: 17px; padding: 16px 0; text-align: center; }
/* 자리 이동 — 이미 손님이 있는 자리도 고를 수 있게 두되(두 테이블을 하나로
   합치는 일이 실제로 있다), 고르기 전에 보이게 표시한다. 숨기면 "왜 저
   자리가 없지" 가 되고, 표시가 없으면 남의 주문에 얹는 줄 모른다. */
.table-picker-btn.occupied { background: #fdf6ec; border-color: #e6d4b8; }
.table-picker-btn .picker-sub { display: block; font-size: 11px; font-weight: 400; color: var(--muted); margin-top: 2px; }
/* 옮겨온 주문 — 주방에는 이미 옛 번호가 찍힌 티켓이 나가 있다. */
.order-card-moved { font-size: 12px; font-weight: 600; color: #8a5a1c; background: #fdf3e2; border-radius: 6px; padding: 1px 6px; margin-left: 6px; }

/* 주문 수정 (edit an already-placed order's items) — see openOrderEdit()
   in admin.js. order-edit-item-row-main always holds name/qty/price/delete
   in the same fixed spots; each option/spice/addons/order-type control gets
   its own order-edit-item-row-choice row below, free to wrap on its own
   without ever moving the delete button (2026-09 피드백). */
.order-edit-item-row {
  padding: 12px 0; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px;
}
.order-edit-item-row-main { display: flex; align-items: center; gap: 10px; }
.order-edit-item-name { flex: 1; min-width: 100px; font-weight: 700; font-size: 15px; }
/* One row per attribute (option, spice, addons, order-type) — see the
   comment above renderDraft()'s row.innerHTML in admin.js for why these
   used to share a row and don't anymore. A line that doesn't have a given
   attribute (no addons, say) renders an empty row here, which just
   collapses instead of leaving a gap. */
.order-edit-item-row-choice {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-left: 2px;
}
.order-edit-item-row-choice:empty { display: none; }
/* Pill-button toggle groups for option/spice/order-type — matches the
   customer order page's own choice picker (.options-list button in
   main.css) instead of a native <select>, which read as visibly
   out-of-place next to the rest of this UI and needed a hand-drawn
   chevron that rendered oversized with no background-size set
   (2026-09 피드백: "드롭다운 화살표가 기괴하게 커" / "10년 전 코드 같다"). */
.order-edit-pill-group { display: flex; gap: 6px; flex-wrap: wrap; }
.order-edit-pill-btn {
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--line); background: #fff;
  font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer;
}
.order-edit-pill-btn:hover { border-color: var(--navy); }
.order-edit-pill-btn.active { background: var(--ink); color: #fff; border-color: var(--ink); }
/* 매장내/포장 (dine-in/takeout) originally got this segmented-switch look
   instead of the plain pill style above, since it's a fundamentally
   different kind of choice from the dish's option/spice pills (which one
   plate is this) — same visual language as the customer order page's own
   .order-type-tabs (main.css). The owner liked it enough to ask for the
   same look on every choice group once each got its own row, not just
   order-type (2026-09 피드백: "토글 디자인은 현재 매장내 포장이 좋아.
   그걸로 다른 애들도 적용해줘"), so this is now a shared modifier class —
   applied via pillGroup()'s extraClass param to option/spice/order-type
   alike in the order-edit item row. The add-item side panel's own
   option/spice/addon pickers (openAddPicker's pillPicker/renderAddons)
   weren't part of that feedback and keep the plain .order-edit-pill-group
   look — addons there is a multi-select list, which this single-row
   segmented-switch shape doesn't represent well. */
.order-edit-pill-group-segmented {
  display: flex; gap: 0; background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px; width: fit-content;
}
.order-edit-pill-group-segmented .order-edit-pill-btn {
  border: none; border-radius: 999px; background: none; padding: 5px 14px;
}
.order-edit-pill-group-segmented .order-edit-pill-btn:hover { border-color: transparent; color: var(--navy); }
.order-edit-pill-group-segmented .order-edit-pill-btn.active { background: var(--ink); color: #fff; }
/* 牛/豬 face icons (cropped from the restaurant's own PDF menu, see
   optionLabel() in order.js/admin.js) shown inside pill buttons/badges. */
.option-icon { height: 16px; width: auto; vertical-align: middle; display: inline-block; }
/* Same icons next to a dish's name wherever admin shows it standalone
   (order-edit item rows, the add-item picker panel name) — see
   meatIconsHtml() in admin.js. */
.item-meat-icons { display: inline-flex; align-items: center; gap: 2px; margin-left: 4px; }
.order-edit-meta-badge {
  font-size: 13px; font-weight: 600; color: var(--muted); background: var(--cream);
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px;
}
.order-edit-qty-group { display: flex; align-items: center; gap: 6px; }
.order-edit-qty-btn {
  width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--line); background: #fff; cursor: pointer;
  font-weight: 800; font-size: 15px; line-height: 1; color: var(--ink); padding: 0;
}
.order-edit-qty-btn:hover { border-color: var(--navy); color: var(--navy); }
.order-edit-qty-value { min-width: 22px; text-align: center; font-weight: 700; }
.order-edit-item-price { font-size: 13px; color: var(--muted); min-width: 60px; text-align: right; }
.order-edit-remove-btn {
  background: none; border: none; color: var(--red); font-size: 18px; font-weight: 800; cursor: pointer; padding: 0 4px;
  flex-shrink: 0;
}
/* Quick-add row (pick a menu item + "+ 추가") — previously a bare native
   <select> and <button> with zero styling, sitting right below a
   carefully-styled item list and looking noticeably dated by comparison
   (2026-09 피드백). Select gets the same rounded/bordered treatment as
   every other form field in this admin (.modal-form input/select), with
   a correctly-sized custom chevron this time; the button reuses the
   site's actual primary-action look instead of the browser default. */
.order-edit-add-row { display: flex; gap: 8px; margin-top: 14px; }
.order-edit-add-row select {
  flex: 1; appearance: none; -webkit-appearance: none; padding: 10px 32px 10px 12px;
  font-size: 15px; font-weight: 600; color: var(--ink); border: 1px solid var(--line);
  border-radius: 8px; background-color: #fff; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23888' stroke-width='1.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 11px 7px;
}
.order-edit-add-row select:hover { border-color: var(--navy); }
.order-edit-add-row button {
  background: var(--red); color: #fff; border: none; padding: 10px 18px; border-radius: 8px;
  cursor: pointer; font-weight: 700; font-size: 15px; white-space: nowrap;
}
.order-edit-add-row button:hover { background: #9b1e26; }
.order-edit-total { text-align: right; font-weight: 800; font-size: 17px; margin-top: 12px; padding-top: 10px; border-top: 2px solid var(--ink); }

/* Two-panel add-item flow (2026-09 피드백): #orderEditBackdrop's one flex
   child lays the 주문 수정 modal and the (initially hidden) add-item picker
   modal out side by side, same size, instead of the picker overlaying on
   top of or replacing the edit modal. See openAddPicker() in admin.js. */
.order-edit-panels { display: flex; align-items: flex-start; gap: 16px; max-width: 96vw; }
.order-edit-picker-modal { width: 400px; flex-shrink: 0; }
.order-edit-picker-photo {
  width: 100%; height: 160px; border-radius: 14px; margin-bottom: 14px;
  background: linear-gradient(150deg, #eeddb8, #ddc088); background-size: cover; background-position: center;
  border: 1px solid var(--line);
}
.order-edit-picker-modal h2 { font-size: 19px; margin: 0 0 14px; }
.order-edit-picker-modal #orderEditPickerOptions,
.order-edit-picker-modal #orderEditPickerSpice,
.order-edit-picker-modal #orderEditPickerAddons { margin-bottom: 12px; }
.order-edit-picker-qty { justify-content: center; margin: 18px 0; }
.order-edit-picker-qty .order-edit-qty-btn { width: 34px; height: 34px; font-size: 18px; }
.order-edit-picker-qty .order-edit-qty-value { font-size: 17px; min-width: 26px; }
@media (max-width: 900px) {
  .order-edit-panels { flex-direction: column; }
  .order-edit-picker-modal { width: 100%; }
}

/* 인앱 확인/알림 (see showConfirm()/showAlert() in admin.js) */
.app-dialog-modal { max-width: 360px; text-align: center; }
/* 인원 수정 — 손가락으로 누르기 좋게 버튼을 크게. */
.party-edit-modal h3 { margin: 0 0 14px; }
.party-edit-row { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 10px 0; font-size: 17px; }
.party-edit-row span { min-width: 52px; text-align: left; }
.party-edit-row button { width: 44px; height: 44px; border-radius: 999px; border: 1px solid var(--line); background: #fff; font-size: 22px; cursor: pointer; }
.party-edit-row strong { min-width: 32px; font-size: 22px; }
.party-edit-total { font-weight: 700; margin: 12px 0 4px; }
.party-edit-hint { font-size: 13px; color: var(--muted); margin: 0 0 16px; line-height: 1.5; }
.app-dialog-modal #appDialogMessage { font-size: 16px; line-height: 1.6; margin: 4px 0 20px; white-space: pre-line; }
.app-dialog-modal .modal-actions { justify-content: center; gap: 10px; }

/* ── 결제 방식 고르는 창만 크게 (2026-09-11) ──────────────────────────
   사장님: "결제창에서 현금, 라인페이, 신용카드 선택하는 창을 좀더 크게
   만들어줘. 설정에서 화면을 크게하면 모든화면이 다 크게 되니까 그 창만 더
   크면 되겠음."

   설정 > 화면 글자 크기는 body 에 zoom 을 걸어 화면 전체를 키운다. 이 창
   하나 때문에 그걸 올리면 주문판까지 커져서 한 화면에 들어오던 것이 안
   들어온다. 그래서 크기를 여기에 따로 박는다. px 로 적어도 zoom 위에서
   곱해지므로, 설정을 올리면 이 창은 그만큼 더 커진다 — 설정을 무시하는
   것이 아니라 출발점만 크게 잡는 것이다.

   네 칸을 2×2 로 놓는다. 한 줄로 늘어놓으면 칸마다 좁아져서, 키운 의미가
   가장 큰 「누르기 쉬움」이 도로 사라진다. */
.payment-method-modal { max-width: 560px; }
.payment-method-modal h2 { font-size: 26px; }
/* 직원이 손님에게 불러주는 금액이다. 고르는 버튼만 키우고 이건 그대로 두면
   정작 확인해야 할 숫자가 제일 작아진다. */
.payment-method-modal #paymentMethodSummary {
  color: var(--muted); font-size: 20px; font-weight: 700; margin: 6px 0 0;
}
.payment-method-modal #paymentMethodHint {
  color: var(--red); font-size: 17px; font-weight: 700; margin: 10px 0 0;
}
.pay-method-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-top: 18px;
}
.pay-method-grid button {
  min-height: 96px; padding: 14px 10px; font-size: 27px; font-weight: 800;
  border-radius: 14px; line-height: 1.2; word-break: keep-all;
}
/* 못 누르는 칸(할인은 현금만)도 크기는 그대로 둔다 — 칸이 작아지면 줄이
   흐트러져서, 「지금은 못 누른다」가 「버튼이 사라졌다」로 읽힌다. */
.pay-method-grid button:disabled { cursor: not-allowed; }
.payment-method-modal .modal-actions { margin-top: 16px; }
/* 나눠 내기(2026-10-18). 여는 단추는 위 네 칸보다 작게 — 대부분은 한 수단으로 낸다. */
.pay-split-open {
  width: 100%; margin-top: 12px; padding: 14px; border-radius: 14px;
  border: 1.5px dashed #cfc5b6; background: #fff; color: #2f3542;
  font-size: 19px; font-weight: 700; cursor: pointer;
}
.pay-split-open:hover { border-color: #2f3542; }
.pay-split-open:disabled { opacity: 0.4; cursor: not-allowed; }
.pay-split { margin-top: 16px; }
.pay-split-due { font-size: 20px; color: var(--muted); font-weight: 700; }
.pay-split-due b { color: var(--ink, #241f1f); font-size: 26px; margin-left: 6px; }
.pay-split-rows { display: grid; gap: 10px; margin-top: 12px; }
.pay-split-row { display: grid; grid-template-columns: 120px 1fr auto; gap: 10px; align-items: center; }
.pay-split-row label { font-size: 21px; font-weight: 800; }
.pay-split-row input {
  min-width: 0; height: 56px; padding: 0 14px; border: 1.5px solid var(--line); border-radius: 12px;
  font-size: 26px; font-weight: 800; text-align: right; font-variant-numeric: tabular-nums;
}
.pay-split-row input:focus { outline: none; border-color: #2f3542; }
.pay-split-row.has-amount input { border-color: #2f3542; background: #f7f5f1; }
.pay-split-row .pay-split-rest {
  height: 56px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--line);
  background: #fff; font-size: 17px; font-weight: 700; cursor: pointer; white-space: nowrap;
}
.pay-split-left { margin-top: 12px; font-size: 21px; font-weight: 800; }
.pay-split-left.is-short { color: var(--red); }
.pay-split-left.is-over { color: var(--red); }
.pay-split-left.is-ok { color: #1f7a3f; }
.pay-split-actions { display: flex; gap: 10px; margin-top: 14px; }
.pay-split-actions button { flex: 1; min-height: 64px; font-size: 21px; font-weight: 800; border-radius: 14px; }
.pay-split-actions .primary-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.payment-method-modal #paymentMethodCancel { padding: 14px 34px; font-size: 20px; border-radius: 12px; }
/* 폰처럼 좁은 화면에서도 2×2 를 지킨다. 한 줄에 하나씩 쌓으면 창이 세로로
   길어져 「기타」가 화면 밖으로 밀린다. */
@media (max-width: 430px) {
  .pay-method-grid { gap: 10px; }
  .pay-method-grid button { min-height: 80px; font-size: 21px; padding: 10px 6px; }
  .payment-method-modal #paymentMethodSummary { font-size: 17px; }
  .pay-split-row { grid-template-columns: 84px 1fr auto; }
  .pay-split-row label { font-size: 17px; }
  .pay-split-row input { font-size: 21px; height: 50px; }
}

/* 주문 아이템 목록 접기/펼치기 (order-card / table-detail item lines) */
.order-items-toggle {
  display: block; width: 100%; margin-top: 6px; padding: 5px 0; background: none; border: none;
  border-top: 1px dashed var(--line); color: var(--navy); font-weight: 700; font-size: 14px; cursor: pointer; text-align: center;
}
.order-items-toggle:hover { color: var(--red); }

/* 주문 큐 카드 드래그 정렬 (see wireCardDrag() in admin.js).
   Pointer Events (not native HTML5 draggable/dragover/drop) so this works
   the same way on a mouse/trackpad AND on a touchscreen tablet — the whole
   card stays a normal tap target (opens the order detail), and only the
   small ⠿ handle in the corner starts a drag. */
.order-card.dragging { opacity: 0.35; }
.order-card-top-right { display: flex; align-items: center; gap: 2px; }
.order-card-drag-handle {
  cursor: grab; touch-action: none; padding: 4px 8px; margin: -4px -6px -4px 0;
  font-size: 17px; line-height: 1; color: var(--muted); user-select: none;
}
.order-card-drag-handle:active { cursor: grabbing; }

/* 테이블 상세 진행중/완료 내역 탭 */
.table-detail-tabs { display: flex; gap: 6px; margin: 10px 0 4px; }
.table-detail-tab-btn {
  flex: 1; padding: 9px 6px; border: 1px solid var(--line); border-radius: 8px; background: #fff; cursor: pointer;
  font-weight: 700; font-size: 15px; color: var(--muted);
}
.table-detail-tab-btn.active { background: var(--navy); color: #fff; border-color: var(--navy); }

@media (max-width: 900px) {
  .orders-board { grid-template-columns: 1fr 1fr; }
  .form-row { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .orders-board { grid-template-columns: 1fr; }
  .admin-tabs { overflow-x: auto; }
}

/* ---------- 계정(계정 관리) 탭 — owner only ---------- */
/* 홈페이지에서 가입한 계정의 등급을 바꾸는 화면. VIP 카드 목록과 같은
   시각 언어를 쓰되, 등급 배지 색으로 사장/직원/손님이 한눈에 갈리게 한다. */
.owner-activity-card {
  max-width: 1100px; margin: 20px 0 28px; padding: 20px;
  border: 1px solid #cfd9e8; border-radius: 16px;
  background: linear-gradient(145deg, #f8fbff 0%, #fff 58%);
  box-shadow: 0 8px 24px rgba(20, 39, 74, 0.06);
}
.owner-activity-heading {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
}
.owner-activity-heading h2, .accounts-list-title {
  margin: 0; color: var(--ink); font-size: 20px;
}
.owner-activity-heading p {
  max-width: 760px; margin: 7px 0 0; color: var(--muted); font-size: 14px; line-height: 1.55;
}
.owner-activity-heading button {
  flex: 0 0 auto; padding: 9px 13px; border: 1px solid #bdcbe0; border-radius: 9px;
  background: #fff; color: var(--navy); font: inherit; font-size: 13px; font-weight: 800; cursor: pointer;
}
.owner-activity-heading button:hover { background: #f1f6fc; }
.owner-activity-summary { margin: 18px 0 10px; color: var(--navy); font-size: 14px; font-weight: 800; }
.owner-activity-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.owner-activity-group {
  min-width: 0; padding: 14px; border: 1px solid #dbe2eb; border-radius: 14px; background: rgba(255,255,255,.72);
}
.owner-activity-group-owner { border-top: 4px solid #c8922d; }
.owner-activity-group-staff { border-top: 4px solid #5279ad; }
.owner-activity-group-heading {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 11px;
}
.owner-activity-group-heading h3 { margin: 0; color: var(--ink); font-size: 17px; }
.owner-activity-group-heading span { color: var(--muted); font-size: 12px; font-weight: 700; text-align: right; }
.owner-activity-group-list { display: grid; gap: 10px; }
.owner-activity-row {
  padding: 14px 15px; border: 1px solid var(--line); border-radius: 12px; background: rgba(255,255,255,.9);
}
.owner-activity-row.is-online { border-color: #9bcbae; box-shadow: inset 3px 0 #2e9b57; }
.owner-activity-row-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; }
.owner-activity-row-head strong { font-size: 15px; word-break: break-all; }
.owner-activity-state {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px;
  border-radius: 999px; background: #eef0f3; color: #626a75; font-size: 12px; font-weight: 800;
}
.owner-activity-state i { width: 8px; height: 8px; border-radius: 50%; background: #9198a1; }
.owner-activity-row.is-online .owner-activity-state { background: #e4f5e9; color: #176b36; }
.owner-activity-row.is-online .owner-activity-state i { background: #2ba653; box-shadow: 0 0 0 3px rgba(43,166,83,.13); }
.owner-activity-method {
  padding: 2px 7px; border: 1px solid #d8dee8; border-radius: 6px; color: var(--muted); font-size: 11px;
}
.owner-activity-role {
  padding: 3px 8px; border-radius: 999px; font-size: 11px; font-weight: 900;
}
.owner-activity-role.is-owner { background: #f7ead1; color: #8b5b06; }
.owner-activity-role.is-staff { background: #e6edf8; color: #315487; }
.owner-activity-current {
  padding: 3px 8px; border-radius: 999px; background: #edf1f5; color: #586474; font-size: 11px; font-weight: 800;
}
.owner-activity-force {
  margin-left: auto; padding: 6px 9px; border: 1px solid #d8a3a3; border-radius: 8px;
  background: #fff7f7; color: #a32626; font: inherit; font-size: 12px; font-weight: 800; cursor: pointer;
}
.owner-activity-force:hover { background: #fdeaea; border-color: #bf7070; }
.owner-activity-force:disabled { opacity: .55; cursor: wait; }
.owner-activity-meta, .owner-activity-times {
  display: flex; flex-wrap: wrap; gap: 5px 16px; margin-top: 8px; color: var(--muted); font-size: 13px;
}
.owner-activity-meta span, .owner-activity-times span { overflow-wrap: anywhere; }
.owner-activity-times { padding-top: 8px; border-top: 1px dashed #e4e8ed; font-size: 12px; }
.owner-activity-empty { margin: 0; padding: 20px 8px; color: var(--muted); text-align: center; font-size: 13px; line-height: 1.55; }
.admin-audit-panel { margin-top: 18px; padding-top: 17px; border-top: 1px solid #dbe2eb; }
.admin-audit-heading h3 { margin: 0; color: var(--ink); font-size: 17px; }
.admin-audit-heading p { margin: 5px 0 12px; color: var(--muted); font-size: 13px; line-height: 1.5; }
.admin-audit-list { display: grid; gap: 7px; max-height: 360px; overflow: auto; padding-right: 3px; }
.admin-audit-row {
  display: grid; grid-template-columns: minmax(180px, .8fr) minmax(260px, 1.2fr); gap: 12px;
  align-items: center; padding: 10px 12px; border: 1px solid #e1e6ec; border-radius: 10px; background: rgba(255,255,255,.78);
}
.admin-audit-row.is-failed { background: #fff8f8; border-color: #e5baba; }
.admin-audit-row-main, .admin-audit-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 9px; }
.admin-audit-row-main strong { font-size: 13px; }
.admin-audit-meta { color: var(--muted); font-size: 12px; }
.admin-audit-failed { padding: 2px 6px; border-radius: 999px; background: #f7dede; color: #9b2525; font-size: 10px; font-weight: 900; }
.accounts-list-title { max-width: 900px; margin-bottom: 12px; }
.accounts-toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; max-width: 900px; }
.accounts-toolbar input {
  flex: 1 1 240px; padding: 10px; border: 1px solid var(--line); border-radius: 8px;
  font-size: 16px; font-family: inherit;
}
.accounts-toolbar button {
  padding: 10px 16px; border: 1px solid var(--line); border-radius: 8px; background: #fff;
  font-size: 14px; font-weight: 700; cursor: pointer; white-space: nowrap;
}
.accounts-list { display: flex; flex-direction: column; gap: 10px; max-width: 900px; }
.account-row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; background: #fff;
}
.account-main { flex: 1 1 260px; min-width: 0; }
.account-name { font-size: 15px; font-weight: 800; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.account-sub { font-size: 13px; color: var(--muted); margin-top: 3px; word-break: break-all; }
.account-role-badge {
  font-size: 11px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
  border: 1px solid transparent; white-space: nowrap;
}
.account-role-badge.owner { background: #fdf0d5; border-color: #e0be6b; color: #7a5a12; }
.account-role-badge.staff { background: #e7f0fb; border-color: #a8c6ea; color: #24527f; }
.account-role-badge.customer { background: #f1f1ef; border-color: var(--line); color: var(--muted); }
.account-actions select {
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
  font-size: 14px; font-family: inherit; background: #fff; cursor: pointer;
}
.account-actions select:disabled { opacity: 0.5; cursor: default; }

@media (max-width: 640px) {
  .owner-activity-card { padding: 15px; }
  .owner-activity-heading { flex-direction: column; }
  .owner-activity-heading button { width: 100%; }
  .owner-activity-meta, .owner-activity-times { flex-direction: column; gap: 4px; }
  .owner-activity-list { grid-template-columns: 1fr; }
  .admin-audit-row { grid-template-columns: 1fr; gap: 5px; }
  .owner-activity-force { width: 100%; margin-left: 0; }
}

/* 「손님 나감 (인원수 비우기)」 — 결제할 게 없는 테이블에만 나온다.
   자주 쓰는 버튼이 아니고 되돌릴 수 있는 동작이라, 결제 버튼처럼 눈에
   확 띄면 안 된다. 다만 태블릿에서 손가락으로 눌러야 하므로 높이는
   충분히 준다. */
.table-detail-clear-party {
  border: 1px solid var(--line);
  background: #fff;
  color: var(--muted);
  border-radius: 8px;
  padding: 8px 14px;
  min-height: 38px;
  font-size: 15px;
  font-family: inherit;
  cursor: pointer;
}
.table-detail-clear-party:hover { border-color: var(--navy); color: var(--navy); }
.table-detail-clear-party:disabled { opacity: 0.5; cursor: default; }

/* 결제창 맨 아래 줄. 「받을 돈」과 VIP 카드 판매 버튼이 왼쪽, 결제 버튼이
   오른쪽. 좁은 화면에서는 줄바꿈된다 — 태블릿을 세로로 쓰는 날이 있다. */
/* 결제 버튼은 **언제나 오른쪽 끝**이다.
 *
 * 2026-09-16 사장님(두 번째): "일단 결제완료가 여전히 왼쪽으로 빠져."
 *
 * 원인은 이 줄의 flex-wrap: wrap 이었다. 왼쪽 묶음(미결제 합계 + VIP카드
 * 판매)이 넓어지면 결제 버튼이 **다음 줄로 넘어갔고**, 혼자 남은 줄에서는
 * justify-content: space-between 이 아무 일도 안 해서 왼쪽에 붙었다.
 * 할인이 걸려 「NT$250 NT$238」로 길어지는 순간 정확히 그렇게 된다 —
 * 사장님 스크린샷이 그 상태다.
 *
 * 이 줄은 안 접는다(nowrap). 대신 왼쪽 묶음이 자기 안에서 접는다. 제일
 * 자주 누르는 버튼이 눌릴 때마다 다른 자리에 있으면 안 된다. */
.table-detail-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
  border-top: 2px solid var(--ink);
  margin-top: 4px;
  padding-top: 12px;
}
/* 남는 자리를 왼쪽이 가져가고, 좁아지면 자기 안에서 줄을 바꾼다.
   min-width: 0 이 없으면 flex 자식이 내용보다 안 줄어들어 버튼을 밀어낸다. */
.table-detail-footer-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
}
/* 버튼은 줄어들지도, 글자가 쪼개지지도 않는다. margin-left: auto 는 왼쪽
   묶음이 비어 있을 때(주문이 없는 자리)도 오른쪽에 붙게 한다. */
.table-detail-footer > .primary-btn {
  flex: 0 0 auto;
  margin-left: auto;
  white-space: nowrap;
}
/* 돈을 받는 버튼이라 결제 버튼과 헷갈리면 안 된다 — 채운 버튼이 아니라
   테두리만 있는 버튼으로 두고, 금액을 버튼 안에 같이 적는다. */
.table-detail-footer .vip-sell-btn {
  border: 1px solid var(--line);
  background: #fff;
  color: var(--muted);
  border-radius: 8px;
  padding: 8px 14px;
  min-height: 38px;
  font-size: 15px;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.table-detail-footer .vip-sell-btn:hover { border-color: var(--navy); color: var(--navy); }
.vip-sell-price { font-size: 26px; font-weight: 700; margin: 4px 0 2px; }
/* app-dialog-modal 은 가운데 정렬이라, 입력칸 라벨만 왼쪽으로 되돌린다. */
#vipSellBackdrop label { text-align: left; }

/* 데이터 저장 공간 경고 띠. 인쇄 실패 띠(.print-fail-banner)와 같은 자리에
   같은 모양으로 뜨지만, 색으로 급한 정도를 나눈다 — "슬슬 준비하자"와
   "지금 해야 한다"는 다른 소식이다. */
.storage-banner {
  font-size: 15px; line-height: 1.6; padding: 12px 16px;
  border-radius: 10px; margin-bottom: 14px; border: 1px solid;
}
.storage-banner.warn { background: #fff7e6; border-color: #d08700; color: #7a4f00; }
.storage-banner.urgent { background: #fdecea; border-color: var(--red); color: var(--red); font-weight: 700; }
.storage-banner-sub { font-weight: 400; font-size: 13.5px; margin-top: 4px; opacity: 0.85; }

/* 설정 칸 아래의 설명 한 줄 — 무엇이 달라지는지 미리 알려주는 자리다. */
.field-hint { display: block; margin-top: 4px; font-size: 13px; color: var(--muted); font-weight: 400; }

/* 요약 카드 아래 붙는 보조 한 줄 — "할인 전 NT$45,000" 처럼 맥락을 준다. */
.settlement-card-sub { margin-top: 4px; font-size: 13px; color: var(--muted); font-weight: 400; }
/* 비중(%) 칸은 숫자가 짧아 오른쪽으로 붙인다. */
.settlement-items-table td.share, .settlement-items-table th.share { text-align: right; white-space: nowrap; }


/* ── 결산 화면 (2026-09-10 다시 짬) ─────────────────────────────────
   사장님: "지금 사실 결산 탭 보는 게 너무 복잡해. 눈에 딱 들어오지도
   않고 뭔가 체계적이지 못한 것 같아."

   위계를 세 단계로 줄인다 — 큰 숫자 하나(매출), 블록 제목, 그 안의 줄.
   같은 크기의 카드를 아홉 개 늘어놓으면 어느 것도 눈에 안 들어온다. */

.stl-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 24px;
  background: var(--navy);
  color: #fff;
  border-radius: 16px;
  padding: 26px 28px;
  max-width: 1560px;
  margin: 0 auto 16px;
}
.stl-hero-main { flex: 1 1 320px; min-width: 0; }
.stl-hero-label { font-size: 15px; opacity: 0.72; letter-spacing: 0.02em; }
/* 이 화면에서 가장 큰 글자. 마감에 제일 먼저 찾는 숫자다. */
.stl-hero-value { font-size: clamp(38px, 5vw, 60px); font-weight: 800; line-height: 1.1; margin-top: 2px; }
.stl-hero-sub { margin-top: 8px; font-size: 15px; opacity: 0.8; }
.stl-hero-side {
  display: grid;
  /* 세 칸씩 — 테이블 수가 들어오며(2026-09-26) 다섯 칸이 됐다. 두 칸씩이면
     한 줄이 늘어 결산 화면이 그만큼 길어진다. 좁은 화면은 아래에서 두 칸. */
  grid-template-columns: repeat(3, minmax(110px, 1fr));
  gap: 10px 26px;
  flex: 0 1 auto;
}
.stl-stat { display: flex; flex-direction: column; gap: 2px; }
.stl-stat-label { font-size: 13px; opacity: 0.7; }
.stl-stat-value { font-size: 20px; font-weight: 700; }
@media (max-width: 720px) {
  .stl-hero { padding: 20px; }
  .stl-hero-side { grid-template-columns: repeat(2, 1fr); width: 100%; }
}

/* 챙겨야 할 것만. 아무 일 없으면 이 줄 자체가 없다. */
.stl-alerts { max-width: 1560px; margin: 0 auto 16px; display: flex; flex-wrap: wrap; gap: 10px; }
.stl-alert {
  border-radius: 10px; padding: 10px 14px; font-size: 15px; font-weight: 700;
  border: 1px solid; background: #fff;
}
.stl-alert.warn { border-color: var(--red); background: #fdecea; color: var(--red); }
.stl-alert.info { border-color: #d08700; background: #fff7e6; color: #7a4f00; }
.stl-alert.dining { border-color: #8aa3c2; background: #eef3fa; color: #2d4a6e; }

.stl-block {
  max-width: 1560px;
  margin: 0 auto 16px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px 22px;
}
.stl-block-warn { border-color: var(--red); }
.stl-block-title { margin: 0 0 14px; font-size: 19px; }
.stl-sub-title { margin: 0 0 10px; font-size: 15px; color: var(--muted); font-weight: 700; }
.stl-note { margin: 10px 0 0; font-size: 13.5px; color: var(--muted); line-height: 1.6; }
.stl-two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
@media (max-width: 860px) { .stl-two-col { grid-template-columns: 1fr; gap: 22px; } }

/* 줄 하나에 이름·금액·막대. 표 대신 막대를 쓰는 이유는 "현금이 절반쯤"
   같은 걸 숫자를 읽지 않고 알 수 있어서다. 그리고 이 막대는 CSS 라서
   차트 라이브러리가 안 뜨는 상황에서도 그대로 보인다. */
/* 막대는 **전부 같은 자리에서 출발한다.**
   사장님(2026-09-11): "그래프 바가 시작이 다 같았으면 좋겠어. 지금은 글
   길이에 따라 시작 위치가 다르잖아."
   그럴 수밖에 없었다 — 줄마다 자기 혼자 grid 라서, 이름 칸이 그 줄의 글자
   길이에 맞춰졌다. 「전통한식요리 76개」가 있는 줄은 막대가 오른쪽에서,
   「음료 11개」가 있는 줄은 왼쪽에서 시작했다. 들쭉날쭉하면 막대 길이를
   서로 견줄 수가 없다 — 막대를 쓰는 이유가 그거인데.
   이제 **묶음 전체가 하나의 grid** 다(줄은 display:contents 로 칸만
   내어준다). 이름 칸이 그 묶음에서 제일 긴 이름 하나로 정해지고, 모든
   줄이 그 자를 같이 쓴다. */
.stl-bars {
  display: grid;
  grid-template-columns: minmax(88px, 220px) 1fr minmax(96px, max-content) 44px;
  align-items: center;
  column-gap: 10px;
  row-gap: 9px;
  font-size: 15px;
}
.stl-bar-row { display: contents; }
.stl-bar-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* span 은 인라인이라 height/width 가 먹지 않는다 — block 으로 바꿔야
   막대가 실제로 그려진다. 처음엔 이걸 빠뜨려서 회색 트랙만 보였다. */
.stl-bar-track { display: block; height: 10px; background: #efeae1; border-radius: 999px; overflow: hidden; }
.stl-bar-fill { display: block; height: 100%; background: var(--navy); border-radius: 999px; min-width: 3px; }
.stl-bar-amount { text-align: right; font-weight: 700; white-space: nowrap; }
.stl-bar-share { text-align: right; color: var(--muted); font-size: 13.5px; white-space: nowrap; }
.stl-bar-count { color: var(--muted); font-size: 13px; margin-left: 6px; }
/* 안내 문구는 칸 하나가 아니라 한 줄을 통째로 쓴다(위 .stl-bars 는 grid). */
.stl-bars-empty { color: var(--muted); font-size: 14px; padding: 6px 0; grid-column: 1 / -1; }
.stl-total-row {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: 12px; padding-top: 10px; border-top: 2px solid var(--ink);
  font-size: 16px;
}

/* 블록 안에서 갈아 끼우는 탭 — 세로로 계속 쌓지 않으려는 것이다. */
.stl-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.stl-tab {
  border: 1px solid var(--line); background: #fff; color: var(--muted);
  border-radius: 999px; padding: 7px 14px; font-size: 14px; font-family: inherit;
  cursor: pointer; min-height: 34px;
}
.stl-tab:hover { border-color: var(--navy); color: var(--navy); }
.stl-tab.active { background: var(--navy); border-color: var(--navy); color: #fff; }
.stl-more {
  margin-top: 10px; border: 1px solid var(--line); background: #fff; color: var(--muted);
  border-radius: 8px; padding: 8px 14px; font-size: 14px; font-family: inherit; cursor: pointer;
  min-height: 36px;
}
.stl-more:hover { border-color: var(--navy); color: var(--navy); }

/* 지난 주문 불러오기 (2026-09-10) — 사장님: "전에 있던 테이블 그거 불러올
   수 있으면 좋겠어." 한 줄에 시간·테이블·금액을 두고, 누르면 그 안에
   무엇을 시켰는지 펼친다. 처음부터 다 펼치면 200건이 벽이 된다. */
.stl-order-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.stl-order-filters input, .stl-order-filters select {
  border: 1px solid var(--line); border-radius: 8px; padding: 9px 11px;
  font-size: 15px; font-family: inherit; min-height: 38px; background: #fff;
}
.stl-order-filters input#settlementOrderSearch { flex: 1 1 260px; min-width: 0; }
.stl-order-filters input#settlementOrderTable { width: 120px; }
.stl-order-filters button {
  border: 1px solid var(--navy); background: var(--navy); color: #fff;
  border-radius: 8px; padding: 9px 18px; font-size: 15px; font-family: inherit;
  cursor: pointer; min-height: 38px;
}
/* 목록 자체가 스크롤된다. 안 그러면 200건이 그대로 세로로 쌓여서, 방금
   짧게 만든 결산 화면이 도로 6,000픽셀이 된다 — 실제로 그렇게 됐고
   테스트가 잡았다. 안쪽에서만 스크롤하면 아래 블록들이 화면 밖으로
   밀려나지 않는다. */
.stl-orders {
  display: flex;
  flex-direction: column;
  max-height: 440px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.stl-order {
  border-top: 1px solid var(--line);
}
.stl-order:last-child { border-bottom: 1px solid var(--line); }
/* 시간 · 자리 · 품목 · 금액 · [인쇄][미리보기] · 펼침표
   (2026-09-11 사장님: "가격이 너무 오른쪽으로 밀려서 벽에 붙어서 불편해보여
    왼쪽으로 위치 이동해줘" / "결산탭에서도 인쇄랑 미리보기 그대로 가능하게")
   금액 오른쪽에 버튼 두 개가 들어오면서 금액이 벽에서 떨어진다. */
.stl-order-head {
  display: grid;
  grid-template-columns: 62px minmax(90px, auto) minmax(0, 1fr) minmax(90px, auto) auto 22px;
  align-items: center; gap: 10px;
  width: 100%; text-align: left;
  padding: 11px 4px; background: none; border: none;
  font-family: inherit; font-size: 15px; cursor: pointer; color: var(--ink);
}
.stl-order-actions { display: flex; gap: 6px; flex: 0 0 auto; }
.stl-order-btn {
  padding: 5px 10px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink);
  border-radius: 7px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.stl-order-btn:hover { background: var(--cream); }
.stl-order-btn:disabled { opacity: .5; cursor: default; }
.stl-order-head:hover { background: #faf7f1; }
.stl-order-time { color: var(--muted); font-variant-numeric: tabular-nums; }
.stl-order-table { font-weight: 700; }
.stl-order-peek { color: var(--muted); font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stl-order-total { text-align: right; font-weight: 700; white-space: nowrap; }
/* 어떻게 받았나 — 현금·카드·LinePay, 결제수단 없음(빨강), 미결제(주황) */
.stl-pay-tags { display: inline-flex; gap: 4px; margin-right: 8px; vertical-align: middle; }
.stl-pay-tag { font-size: 12px; font-weight: 700; color: #3d4a5c; background: #eef1f5; border-radius: 999px; padding: 1px 8px; }
.stl-pay-tag.is-none { color: #fff; background: #b3261e; }
/* 나눠 낸 결제 — 수단마다 금액까지(2026-10-18). */
.stl-pay-tag.is-split { color: #1f4e79; background: #e4eef8; font-variant-numeric: tabular-nums; }
.stl-pay-tag.is-open { color: #8a4b00; background: #ffe8c2; }
.stl-order-caret { color: var(--muted); text-align: center; }
.stl-order-body { padding: 2px 4px 14px 72px; font-size: 14.5px; color: var(--ink); }

/* 한 손님이 여러 번에 나눠 시킨 것 — 결산에서는 한 줄로 묶는다
   (admin.js groupSettlementOrders, 2026-09-23 사장님). 묶였다는 것이
   **보여야** 한다. 안 보이면 금액이 왜 큰지 알 수 없다. */
.stl-order-rounds {
  font-weight: 600;
  font-size: 13px;
  color: var(--muted);
  background: var(--cream);
  border-radius: 999px;
  padding: 1px 8px;
  white-space: nowrap;
}
/* 펼쳤을 때 라운드 하나하나. 왼쪽 선으로 「이 묶음에 속한 것」임을 보인다. */
.stl-order-round { border-left: 3px solid var(--line); margin: 0 4px 4px 60px; }
.stl-order-round-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 8px 4px 12px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--muted);
}
/* 라운드 안에서는 왼쪽 여백을 줄인다 — 위에서 이미 한 번 들여썼다. */
.stl-order-round .stl-order-body { padding-left: 12px; }
/* 태블릿 세로처럼 좁으면 품목 미리보기를 접고 버튼을 살린다 — 품목은 줄을
   펼치면 다 보이지만, 인쇄 버튼은 여기 말고는 갈 곳이 없다. */
@media (max-width: 900px) {
  .stl-order-head { grid-template-columns: 56px minmax(70px, auto) minmax(0, 1fr) auto 18px; }
  .stl-order-peek { display: none; }
  .stl-order-btn { padding: 5px 8px; font-size: 12px; }
}
.stl-order-line { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; }
.stl-order-line-sub { color: var(--muted); font-size: 13px; padding-left: 12px; }
.stl-order-meta { margin-top: 8px; color: var(--muted); font-size: 13px; line-height: 1.7; }
.stl-order.cancelled .stl-order-table, .stl-order.cancelled .stl-order-total { text-decoration: line-through; opacity: 0.6; }

/* ── 테스터 모드 (src/testMode.js) ─────────────────────────────────────
   켜져 있다는 것을 놓칠 수 없어야 한다. 놓치면 테스트 주문을 진짜로
   착각하거나, 켜둔 줄 모르고 하루를 보낸다. 그래서 색은 가게 색이 아니라
   일부러 튀는 색이고, 배너는 화면 맨 위에 고정된다. */
.test-mode-banner {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  background: repeating-linear-gradient(45deg, #7c2d12, #7c2d12 14px, #9a3412 14px, #9a3412 28px);
  color: #fff;
  font-weight: 700;
  font-size: 15px;
}
.test-mode-banner-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fde68a;
  flex: none;
  animation: testModePulse 1.4s ease-in-out infinite;
}
@keyframes testModePulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}
/* 참여하지 않은 기기 — 켜져 있다는 것은 알려야 하지만, 이 기기의 주문은
   진짜로 남으므로 「위험」으로 읽히면 안 된다. 같은 자리, 다른 목소리. */
.test-mode-banner.is-other {
  background: #78350f;
  color: #fef3c7;
  font-weight: 600;
}
.test-mode-banner.is-other .test-mode-banner-dot { background: #fbbf24; animation: none; }
.test-mode-banner.is-other .test-mode-banner-btn { background: #fef3c7; color: #78350f; }
/* 아무도 참여 중이 아닌 상태 — 위험하지도 정상적이지도 않다. 「치워야 할
   것이 남아 있다」에 가깝다. */
.test-mode-banner.is-idle { background: #92400e; }
.test-mode-banner.is-idle .test-mode-banner-dot { background: #fed7aa; animation: none; }
#testModeBannerText { flex: 1; }
.test-mode-banner-btn {
  flex: none;
  background: #fff;
  color: #7c2d12;
  border: 0;
  border-radius: 6px;
  padding: 5px 12px;
  font-weight: 700;
  cursor: pointer;
}
.test-mode-state { margin: 8px 0 4px; }
.test-mode-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.test-mode-phone { margin-top: 10px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.test-mode-phone input { flex: 1; min-width: 220px; font-size: 13px; padding: 6px 8px; }
/* 테스트 주문은 주문판에서 한눈에 갈려야 한다. */
.order-card.test-order { outline: 2px dashed #9a3412; outline-offset: -2px; }
.order-card-test-badge {
  display: inline-block;
  background: #9a3412;
  color: #fff;
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 700;
  margin-left: 6px;
}

/* 이번 결제에 얹어 둔 VIP 카드 — 눌러 둔 상태라는 것이 한눈에 보여야
   한다. 결제 금액이 이미 그만큼 커져 있기 때문이다. */
.vip-sell-btn.is-pending {
  background: #1f7a3d;
  border-color: #1f7a3d;
  color: #fff;
}
.vip-sell-pending-note {
  margin-left: 8px;
  font-size: 13px;
  color: var(--muted, #777);
}

/* 위치 확인이 안 된 주문. 경고가 아니라 사실 표시다 — 빨간색을 쓰면
   직원이 「막아야 하는 주문」으로 읽는다. */
.order-card-loc-unverified {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 10px;
  background: #eef1f5;
  color: #5a6472;
  font-size: 12px;
  white-space: nowrap;
}

/* 설정 카드 안의 켜기/끄기 한 줄. */
.settings-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0 10px;
  font-weight: 600;
}
.settings-switch input { width: 18px; height: 18px; }

/* 손님 수 아래 어른·아이 한 줄. 값보다 작고 흐리게 — 설명이지 주인공이
   아니다(사장님: "결산 탭 보는 게 너무 복잡해"). */
.stl-stat-sub {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted, #777);
  font-weight: 600;
}

/* ── 오전 / 오후 (2026-09-10) ─────────────────────────────────────────
   사장님: "그 밑에 박스를 넣어주고 똑같은 크기로 그리고 좌우를 나눠서
   좌는 오전 매출 우는 오후 매출... 합산은 합산이라는 걸 누가봐도 알 수
   있게 되어쓰면 좋겠어. 예를 들어 오전 오후 매출은 다른 색으로."

   합산(위 hero)은 남색, 오전은 주황(🌅), 오후는 보라(🌙). 정산 버튼의
   아이콘과 같은 짝이라 새로 외울 것이 없다. 두 칸은 1fr 1fr 로 정확히
   같은 크기다 — 한쪽이 커 보이면 그날 매출이 그런 줄 안다. */
.stl-halves {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 12px;
}
.stl-half {
  border: 2px solid;
  border-radius: 12px;
  padding: 14px 16px;
  background: #fff;
}
.stl-half-am { border-color: #e08a1e; background: #fffaf2; }
.stl-half-pm { border-color: #6a4fb3; background: #f8f6fd; }
.stl-half-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.stl-half-title { font-size: 15px; font-weight: 800; }
.stl-half-am .stl-half-title { color: #b8690a; }
.stl-half-pm .stl-half-title { color: #533a95; }
.stl-half-range { font-size: 12px; color: #777; }
.stl-half-value { font-size: 28px; font-weight: 800; margin: 6px 0 10px; letter-spacing: -0.5px; }
.stl-half-am .stl-half-value { color: #b8690a; }
.stl-half-pm .stl-half-value { color: #533a95; }
.stl-half-stats { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px 12px; margin: 0; }
.stl-half-stats > div { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.stl-half-stats dt { font-size: 12px; color: #666; margin: 0; }
.stl-half-stats dd { font-size: 14px; font-weight: 700; margin: 0; }
.stl-halves-note { margin: 8px 0 0; font-size: 12px; color: #b5232c; font-weight: 600; }

/* 눌러서 그 시간대만 보기 (2026-09-10 사장님: "Shift 별로 클릭하면 해당
   Shift만 볼 수 있으면 더 디테일할거야").

   누를 수 있다는 것이 보여야 누른다. 손가락 커서와 살짝 뜨는 그림자로
   「이건 버튼이다」를 말하고, 고른 칸은 테두리를 굵혀 남긴다 — 고른 표시가
   약하면 아래 숫자가 왜 작아졌는지 모르게 된다. */
.stl-half { cursor: pointer; transition: box-shadow .12s, transform .12s; }
.stl-half:hover { box-shadow: 0 2px 10px rgba(0, 0, 0, .10); transform: translateY(-1px); }
.stl-half:focus-visible { outline: 3px solid #16213e; outline-offset: 2px; }
.stl-half.is-active { box-shadow: 0 0 0 3px rgba(22, 33, 62, .18); }
.stl-half-am.is-active { background: #fff2dd; }
.stl-half-pm.is-active { background: #efeafc; }
/* 고르지 않은 반대편 칸은 한 발 물러난다. 두 칸이 똑같이 진하면 지금
   무엇을 보고 있는지가 안 보인다. */
.stl-halves.has-shift .stl-half:not(.is-active) { opacity: .55; }
.stl-half-cta { margin-left: auto; font-size: 11px; font-weight: 700; color: #888; white-space: nowrap; }
.stl-half-am.is-active .stl-half-cta { color: #b8690a; }
.stl-half-pm.is-active .stl-half-cta { color: #533a95; }

/* 지금 오전만/오후만 보고 있다는 표와, 합산으로 돌아가는 버튼. */
.stl-shift-badge {
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  vertical-align: middle;
  color: #fff;
}
.stl-shift-badge.am { background: #b8690a; }
.stl-shift-badge.pm { background: #533a95; }
.stl-shift-reset {
  margin-left: 6px;
  padding: 2px 10px;
  border: 1px solid #c9cede;
  border-radius: 999px;
  background: #fff;
  font-size: 11px;
  font-weight: 700;
  color: #16213e;
  cursor: pointer;
  vertical-align: middle;
}
.stl-shift-reset:hover { background: #eef1f8; }
.stl-shift-note { margin: 8px 0 0; font-size: 12px; color: #555; font-weight: 600; }

/* 위의 큰 숫자가 합산이라는 표. 아래 두 칸과 색이 다른 이유다. */
.stl-total-badge {
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 999px;
  background: #16213e;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  vertical-align: middle;
}

/* 폰에서는 좌우가 아니라 위아래로. 좁은 화면에서 억지로 반씩 나누면
   숫자가 줄바꿈되어 오히려 안 읽힌다. */
@media (max-width: 640px) {
  .stl-halves { grid-template-columns: 1fr; }
  .stl-half-stats { grid-template-columns: 1fr 1fr; }
}

/* 진단 · 속도 (2026-09-12) — 표가 좁은 화면에서 잘리지 않게 가로로만 넘긴다. */
.diag-range { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.diag-h { margin: 14px 0 6px; font-size: 0.95em; }
.diag-line { margin: 6px 0; }
.diag-warn { color: #b00020; font-weight: 600; }
.diag-scroll { overflow-x: auto; }
.diag-table { border-collapse: collapse; width: 100%; font-size: 0.9em; }
.diag-table th, .diag-table td { border: 1px solid var(--line, #ddd); padding: 4px 8px; text-align: right; white-space: nowrap; }
.diag-table th:first-child, .diag-table td:first-child { text-align: left; }
.diag-table th { background: var(--bg-soft, #f6f6f6); font-weight: 600; }

/* 결산을 불러오는 중 (2026-09-12) — 사장님: "결산탭을 누르거나 날짜를
   변경하면 이 상태가 정지상태가 너무 오래 유지돼".

   기다리는 동안 **앞의 숫자를 지우지 않는다.** 지우면 새 값이 올 때까지
   근거 없는 0 을 보게 되고, 그건 「매출이 없다」로 읽힌다. 흐리게만 둔다.
   누르는 것도 막는다 — 기다리는 중에 또 누르면 요청만 쌓인다. */
.stl-loading { display: none; }
.stl-busy .stl-loading {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  margin-bottom: 10px;
  border-radius: 10px;
  background: var(--bg-soft, #f3f4f6);
  font-weight: 600;
}
.stl-busy .settlement-content > *:not(.stl-loading) {
  opacity: 0.45;
  pointer-events: none;
  transition: opacity 0.15s ease;
}
.stl-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: stl-spin 0.7s linear infinite;
  flex: 0 0 auto;
}
@keyframes stl-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .stl-spinner { animation: none; } }

/* ── 메뉴 휴지통 ──────────────────────────────────────────────────────
   2026-09-15 사장님: "삭제는 휴지통을 하나 만들어서 복원 버튼을". */
.menu-trash-list { max-height: 52vh; overflow-y: auto; }
.menu-trash-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 2px; border-bottom: 1px solid var(--line);
}
.menu-trash-row:last-child { border-bottom: none; }
.menu-trash-info { min-width: 0; }
.menu-trash-name { font-weight: 700; font-size: 15px; overflow-wrap: anywhere; }
.menu-trash-meta { color: var(--muted); font-size: 13px; margin-top: 2px; }
.menu-trash-restore { flex: none; padding: 8px 16px; font-size: 14px; }

/* 메뉴 관리의 분류 머리에 붙는 「할인 제외」 토글. 2026-09-16 사장님이 같은
   요청("할인은 기타, 음료 는 모두 적용 안돼")을 두 번 하신 뒤 — 예전에는
   코드 안 목록으로만 정해서 제대로 걸렸는지 볼 자리가 없었다. */
.cat-discount-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  vertical-align: middle;
}
.cat-discount-toggle input { width: 15px; height: 15px; cursor: pointer; }
.cat-discount-toggle input:disabled { cursor: default; }

/* 메뉴 이름 옆의 「할인 적용/안 함」 표 — 2026-09-16 사장님: "모든 주문마다
   할인 적용 온 오프 할 수 있게 메뉴 관리에서 할 수 있게 해줘."
   분류를 그냥 따르는 메뉴에는 안 붙는다(admin.js discountFlagBadgeHtml) —
   전부에 붙이면 정작 예외인 줄이 안 보인다. */
.item-discount-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 600;
  vertical-align: middle;
  white-space: nowrap;
}
.item-discount-badge.off {
  background: #fdecec;
  color: #a3302c;
}
.item-discount-badge.on {
  background: #e8f3ec;
  color: #1f6b3c;
}

/* ── 메뉴 수정의 「미리보기」 탭 ─────────────────────────────────────────
   2026-09-16 사장님: "옵션 탭이 지금 너무 혼잡해 읽어도 이해가 안되는 부분이
   꽤 있어서 (…) 폰에서 어떻게 보이는지 실제 ui 코드를 랜더링해서 보여주면
   좋을 것 같아."

   손님 화면을 불러오지 않는다. 폼에 적힌 값으로 같은 모양을 그릴 뿐이고,
   누를 수 있는 것은 없다(admin.js renderItemPreview). 「하나만 고르는 것」과
   「여러 개 고르는 것」의 차이는 글보다 그림이 빠르다. */
.item-form-pane-preview { display: flex; flex-direction: column; gap: 12px; }
.phone-preview {
  width: 320px;
  max-width: 100%;
  margin: 0 auto;
  border: 10px solid #1f2937;
  border-radius: 28px;
  background: #1f2937;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}
.phone-preview-screen {
  background: #fff;
  border-radius: 20px;
  overflow: hidden;
  /* 손님 폰에서 한 화면에 들어오는 만큼만 보여준다. 넘치면 굴린다. */
  max-height: 60vh;
  overflow-y: auto;
  font-size: 14px;
  color: var(--ink);
  /* 보기만 하는 그림 — 눌리지 않는다. */
  pointer-events: none;
  user-select: none;
}
.pv-photo { height: 140px; background: #f3f0ea center/cover no-repeat; }
.pv-photo-empty { display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 13px; }
.pv-body { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.pv-name { font-weight: 800; font-size: 17px; }
.pv-price { font-weight: 700; color: var(--red); }
.pv-price s { color: var(--muted); font-weight: 500; margin-right: 4px; }
.pv-desc { color: var(--muted); font-size: 13px; line-height: 1.5; }
.pv-group { display: flex; flex-direction: column; gap: 7px; }
.pv-group-title { font-size: 12px; font-weight: 700; color: var(--muted); }
.pv-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pv-chip { border: 1px solid var(--line); border-radius: 999px; padding: 6px 12px; font-size: 13px; }
.pv-chip.picked { background: var(--navy); border-color: var(--navy); color: #fff; font-weight: 700; }
.pv-check { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.pv-box { width: 16px; height: 16px; border: 1.5px solid var(--line); border-radius: 4px; flex: none; }
.pv-check-price { margin-left: auto; color: var(--muted); }
.pv-qty { display: flex; align-items: center; gap: 14px; font-size: 15px; }
.pv-qty span { width: 30px; height: 30px; border: 1px solid var(--line); border-radius: 8px; display: flex; align-items: center; justify-content: center; }
.pv-note { font-size: 12px; color: var(--muted); }
.pv-cta { background: var(--red); color: #fff; text-align: center; font-weight: 800; padding: 14px; font-size: 15px; }

/* 결제창 품목의 옵션 값 줄 — 2026-09-16 사장님: "결제할 때 차라리 추가
   옵션들도 하위 항목들로 가격 다 나오게 해줘. 그리고 옵션들은 할인이 적용
   안되어야 해." 위 품목 줄에는 밥값만(할인이 걸리는 금액), 여기에는 옵션
   값이 정가 그대로 한 줄씩 나온다 — 보이는 줄을 그냥 더하면 소계가 된다.
   (public/js/admin.js payItemSubLinesHtml) */
.pay-item-sub {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 14px;
  color: var(--muted);
  padding-left: 24px; /* 체크박스(16px) + margin(8px) 만큼 들여쓴다 */
}
.pay-item-sub-name {
  min-width: 0;
  overflow-wrap: anywhere;
}
.pay-item-sub-price {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* 옵션이 붙은 품목의 「품목 합계」 — 2026-09-16 사장님: "메뉴 가격 밑에
   옵션들 가격 해서 밑에 총 가격으로도 해야 할 것 같은데?" 밥값(할인가) +
   옵션 값들을 더한, 이 품목에서 실제로 받을 돈. */
.pay-item-sub.pay-item-total {
  color: var(--ink);
  font-weight: 700;
  margin-top: 2px;
  padding-top: 3px;
  border-top: 1px dashed var(--line);
}

/* 결제창 맨 위의 「테스트 테이블」 안내 — 여기서 누른 결제 완료는 결산
   어디에도 안 남는다(2026-09-16 사장님). 직원이 그걸 모르고 진짜 손님을
   여기서 받으면 받은 돈이 통째로 사라진 것처럼 보인다. */
.test-table-notice {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 6px 0 10px;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px dashed #b4870a;
  background: #fff8e6;
  color: #7a5c06;
  font-size: 13px;
  line-height: 1.45;
}
.test-table-notice strong { font-size: 14px; font-weight: 800; }

/* 지난 주문의 할인 내역 — 2026-09-16 사장님: "이전 주문 탭에서도 할인
   내역이 보여야 해 결산에서 그 전 주문들을 볼 때도 보여야 하고."
   결제가 끝난 라운드는 그때 깎아준 금액이 주문에 적혀 있다. 소계 옆에
   원래 금액을 회색 취소선으로 두고, 그 아래 무슨 할인이었는지 한 줄. */
.round-discount-note {
  margin-top: 2px;
  text-align: right;
  font-size: 12px;
  font-weight: 600;
  color: var(--red);
}
/* 결산 목록의 지난 주문 줄 — 할인 전 금액은 회색 취소선으로 옆에 둔다. */
.stl-order-total-was {
  color: var(--muted);
  text-decoration: line-through;
  font-weight: 500;
  margin-right: 4px;
}

/* 패드 프로필 (2026-09-29) — 위쪽 「📍 주방」과 고르는 창. */
.pad-profile-badge { background: rgba(255,255,255,0.14); border: 1px solid rgba(255,255,255,0.35); color: #fff; padding: 6px 10px; border-radius: 999px; cursor: pointer; font-size: 15px; font-weight: 700; white-space: nowrap; max-width: 150px; overflow: hidden; text-overflow: ellipsis; flex: 0 0 auto; }
.pad-profile-badge.is-empty { font-weight: 400; color: #cfd3e0; }
.pad-profile-choices { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin: 14px 0; }
.pad-profile-choices button { padding: 18px 12px; font-size: 20px; font-weight: 700; border-radius: 12px; border: 2px solid var(--line); background: #fff; cursor: pointer; }
.pad-profile-choices button.is-current { border-color: var(--navy); background: #eef1f8; }
.pad-profile-choices button small { display: block; font-size: 13px; font-weight: 400; color: var(--muted); margin-top: 4px; }
/* 설정 카드의 기본(label 한 줄 통째·input/select 폭 100%)을 이 줄에서만 푼다 —
   2026-09-29 사장님 화면: 이름 칸·프린터 칸이 따로 놀고 ✕ 가 「자동 인쇄」
   글자를 덮었다. 선택자를 .settings-card 로 시작해 기본 규칙보다 세게 한다. */
.settings-card .pad-profile-row { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; margin: 0 0 10px; }
.settings-card .pad-profile-fields { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.settings-card .pad-profile-fields input.pad-profile-name { flex: 1 1 140px; width: auto; min-width: 0; margin: 0; }
.settings-card .pad-profile-fields select.pad-profile-printer { flex: 2 1 200px; width: auto; min-width: 0; margin: 0; }
.settings-card .pad-profile-fields label.pad-profile-auto-label { display: inline-flex; align-items: center; gap: 6px; margin: 0; white-space: nowrap; color: inherit; font-size: 16px; cursor: pointer; }
.settings-card .pad-profile-fields label.pad-profile-auto-label input { width: 20px; height: 20px; margin: 0; padding: 0; flex: 0 0 auto; }
.settings-card .pad-profile-fields button.pad-profile-del { flex: 0 0 auto; width: 40px; height: 40px; padding: 0; margin-left: auto; }
.settings-card .pad-profile-devices { margin-top: 8px; font-size: 14px; }
.settings-card .pad-profile-devices-head { color: var(--muted); }
.settings-card .pad-profile-devices ul { list-style: none; margin: 4px 0 0; padding: 0; }
.settings-card .pad-device { padding: 4px 0; border-top: 1px dashed var(--line); }
.settings-card .pad-device-warn { display: block; color: #d9534f; font-weight: 700; }
.settings-card .pad-device-ago.is-off { color: var(--muted); }
.settings-card .pad-profile-loose { border-top: 1px solid var(--line); padding-top: 8px; margin-bottom: 10px; }
.pad-touch-table { border-collapse: collapse; margin-top: 6px; }
.pad-touch-table th, .pad-touch-table td { border-bottom: 1px solid var(--line); padding: 6px 12px; text-align: right; }
.pad-touch-table th:first-child, .pad-touch-table td:first-child { text-align: left; }
@media (max-width: 1100px) {
  .pad-profile-badge { font-size: 14px; padding: 5px 8px; max-width: 110px; }
}
/* 📍 가 붙으면서 960 폭에서 탭 자리가 17px 모자랐다 — 위 줄 간격·언어 버튼을 조금 줄인다. */
@media (max-width: 1000px) {
  .admin-topbar { gap: 8px; }
  .admin-lang-btn { padding: 5px 7px; font-size: 14px; }
  .pad-profile-badge { padding: 4px 7px; }
}
.settings-card .pad-device-main { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; }
.settings-card .pad-device-main select.pad-device-move { width: auto; margin: 0; padding: 4px 8px; font-size: 14px; }
/* 위 여백(mm) 줄 — 굵기 칸 자리에 「mm」 를 둔다(2026-09-30). */
.ticket-top-margin-field { border-top: 1px dashed var(--line); padding-top: 10px; }
.ticket-font-field .ticket-top-margin-unit { flex: none; width: 64px; text-align: center; color: var(--muted); font-size: 14px; }
/* 이 패드의 앱 판·지금 찍는 곳 — 늘 보이는 작은 한 줄(2026-09-30). */
.printer-pick .printer-pick-status { flex-basis: 100%; font-size: 13px; color: var(--muted); white-space: normal; }
.printer-pick .printer-pick-status.is-old { color: #b5232c; font-weight: 700; }

/* 요즘 달라진 메뉴(2026-09-30) — 어제까지 7일 vs 그 전 주 평균. */
.stl-movers { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px 28px; }
.stl-movers-col h4 { margin: 4px 0 8px; font-size: 16px; }
.stl-mover { display: grid; grid-template-columns: minmax(0, 1fr) 70px minmax(64px, auto); align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.stl-mover-main { min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
.stl-mover-name { font-weight: 700; font-size: 16px; }
.stl-mover-sub { flex-basis: 100%; font-size: 13px; color: var(--muted); }
.stl-mover-soldout { font-size: 12px; font-weight: 700; color: #b5232c; border: 1px solid currentColor; border-radius: 4px; padding: 0 4px; }
.stl-mover-tag { text-align: right; font-weight: 800; font-size: 15px; white-space: nowrap; }
.stl-mover.is-up { color: inherit; }
.stl-mover.is-up .stl-mover-tag, .stl-mover.is-up .stl-mover-spark { color: #1a8a44; }
.stl-mover.is-down .stl-mover-tag, .stl-mover.is-down .stl-mover-spark { color: #c2410c; }
.stl-movers-count b.is-up { color: #1a8a44; }
.stl-movers-count b.is-down { color: #c2410c; }
/* 하루 전체 / 점심 / 저녁 · 시간대가 바뀐 메뉴(2026-09-30). */
.stl-movers-shift { display: inline-flex; gap: 4px; margin-bottom: 8px; }
.stl-movers-shift button { padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: inherit; cursor: pointer; font-size: 14px; }
.stl-movers-shift button.active { background: var(--navy); color: #fff; border-color: var(--navy); font-weight: 700; }
.stl-movers-period { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.stl-movers-range { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
.stl-movers-range input[type="date"] { padding: 5px 8px; border-radius: 8px; border: 1px solid var(--line); background: transparent; color: inherit; font-size: 14px; }
.stl-time-shift { margin-top: 18px; }
.stl-time-shift h4 { margin: 4px 0 4px; font-size: 16px; }
.stl-shift-bars { display: flex; flex-direction: column; gap: 3px; width: 70px; }
.stl-shift-bar { display: block; height: 6px; border-radius: 3px; background: rgba(127,127,127,0.18); overflow: hidden; }
.stl-shift-bar i { display: block; height: 100%; background: #c8a24b; }
.stl-shift-bar.is-before i { opacity: 0.45; }
.stl-movers-count b.is-shift { color: #8a6d1a; }

/* 결제된 것의 반품·취소(2026-10-03). */
.order-refund-btn { color: #b5232c; }
.order-card-total .order-card-refunded { color: #b5232c; }
.order-refunded-tag { font-size: 12px; font-weight: 700; color: #b5232c; border: 1px solid currentColor; border-radius: 4px; padding: 0 4px; }
.refund-modal { max-width: 520px; width: calc(100vw - 32px); }
.refund-hint { font-size: 14px; color: var(--muted); margin: 4px 0 8px; line-height: 1.5; }
.refund-table { font-weight: 700; margin: 0 0 8px; }
.refund-lines { max-height: 46vh; overflow-y: auto; border-top: 1px solid var(--line); }
.refund-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.refund-line-name { min-width: 0; font-size: 16px; font-weight: 700; }
.refund-line-name small { display: block; font-weight: 400; font-size: 13px; color: var(--muted); }
.refund-kind { font-size: 12px; font-weight: 700; border-radius: 4px; padding: 1px 6px; margin-left: 4px; }
.refund-kind.is-cancel { background: #fde8e8; color: #b5232c; }
.refund-kind.is-return { background: #e6f2ea; color: #1a6b38; }
.refund-step { display: inline-flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.refund-step button { width: 40px; height: 40px; border-radius: 8px; border: 1px solid var(--line); background: transparent; color: inherit; font-size: 20px; cursor: pointer; }
.refund-step button:disabled { opacity: 0.35; cursor: default; }
.refund-step strong { min-width: 22px; text-align: center; font-size: 18px; }
.refund-row { display: flex; align-items: center; gap: 10px; margin: 12px 0 8px; }
.refund-row select { flex: 1; }
#refundReason { width: 100%; }
.refund-total { font-size: 18px; font-weight: 800; text-align: right; margin: 10px 0 0; }

/* 직원 급여(2026-10-03) — 출근 카드 한 표.
   2026-10-03 사장님: "ui 좀 더 다듬어줘. 좀 더 직관적이고 부드럽게" — 흰 카드·둥근 모서리·
   옅은 그림자, 입력칸은 높이 40px 로 맞추고, 상태는 색 점과 알약 모양으로 말한다. */
.payroll-tab { --pr-card: #fff; --pr-soft: #f4efe6; --pr-blue: #1f6fb5; --pr-amber: #e0a800; --pr-amber-bg: rgba(240, 180, 0, 0.16); --pr-red: #b5232c; --pr-green: #1f8a4c; }
.payroll-tab .pr-card { background: var(--pr-card); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 1px 2px rgba(36, 31, 31, 0.04), 0 6px 18px rgba(36, 31, 31, 0.05); }

/* 버튼 */
.pr-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 40px; padding: 0 16px; border-radius: 10px; border: 1px solid var(--line); background: var(--pr-card); color: var(--ink); font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; transition: background 0.15s, border-color 0.15s, transform 0.05s, box-shadow 0.15s; white-space: nowrap; }
.pr-btn:hover { border-color: #cfc6b6; background: #fbf8f2; }
.pr-btn:active { transform: translateY(1px); }
.pr-btn-ghost { background: transparent; }
.pr-btn-danger { color: var(--pr-red); }
.pr-btn-danger:hover { background: rgba(181, 35, 44, 0.06); border-color: rgba(181, 35, 44, 0.3); }
.pr-btn-accent { background: #eef4fb; border-color: #c8dbef; color: var(--pr-blue); }
.pr-btn-accent:hover { background: #e2edf9; border-color: #a9c7e6; }
.pr-btn-primary { background: var(--navy); border-color: var(--navy); color: #fff; height: 46px; font-size: 16px; }
.pr-btn-primary:hover { background: #22305a; border-color: #22305a; }
.pr-icon-btn { width: 36px; height: 36px; border-radius: 10px; border: 1px solid var(--line); background: var(--pr-card); color: var(--ink); font-size: 22px; line-height: 1; cursor: pointer; }
.pr-icon-btn:hover { background: #fbf8f2; }

/* 위: 달 · 직원 */
.pr-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; margin: 4px 0 10px; }
.pr-month { display: inline-flex; align-items: center; gap: 6px; padding: 4px; border-radius: 12px; background: var(--pr-card); border: 1px solid var(--line); }
.pr-month-pick { position: relative; display: inline-flex; }
.pr-month-label { height: 36px; min-width: 112px; border: none; background: transparent; font: inherit; font-size: 16px; font-weight: 700; color: var(--ink); padding: 0 6px; cursor: pointer; }
/* 진짜 달 칸은 보이지 않게 밑에 깐다 — showPicker() 로 달력만 연다. */
.pr-month-pick input[type="month"] { position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; opacity: 0; border: 0; padding: 0; pointer-events: none; }
.payroll-chips { display: flex; flex-wrap: wrap; gap: 8px; flex: 1 1 auto; }
.payroll-chips button { display: inline-flex; align-items: baseline; gap: 6px; height: 40px; padding: 0 16px; border-radius: 999px; border: 1px solid var(--line); background: var(--pr-card); color: var(--ink); cursor: pointer; font: inherit; font-size: 15px; font-weight: 600; transition: background 0.15s, box-shadow 0.15s; align-items: center; }
.payroll-chips button:hover { box-shadow: 0 2px 8px rgba(36, 31, 31, 0.08); }
.payroll-chips button.active { background: var(--navy); color: #fff; border-color: var(--navy); }
.payroll-chips button.is-inactive { opacity: 0.5; }
.payroll-chips small { font-size: 13px; font-weight: 500; opacity: 0.8; }
.pr-add { display: inline-flex; gap: 8px; align-items: center; }
.pr-add input { height: 40px; padding: 0 12px; border: 1px solid var(--line); border-radius: 10px; font: inherit; font-size: 15px; background: var(--pr-card); color: var(--ink); width: 150px; }
.pr-info { margin-bottom: 14px; }
.payroll-hours { display: inline-block; font-size: 13px; margin: 0 0 6px; padding: 6px 12px; border-radius: 999px; background: var(--pr-soft); color: #6b625a; }
.payroll-hours.is-bad { background: rgba(181, 35, 44, 0.1); color: var(--pr-red); font-weight: 700; }
.payroll-summary { font-size: 14px; color: #6b625a; }

/* 직원 설정 카드 */
.pr-staff { padding: 16px 18px; margin-bottom: 14px; }
.payroll-staff-form { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 14px; }
.pr-name { height: 40px; padding: 0 12px; border: 1px solid var(--line); border-radius: 10px; font: inherit; font-size: 18px; font-weight: 700; color: var(--ink); background: transparent; width: 200px; }
.pr-seg { display: inline-flex; padding: 3px; border-radius: 12px; background: var(--pr-soft); }
.pr-seg button { height: 34px; padding: 0 18px; border: none; border-radius: 9px; background: transparent; color: #6b625a; font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; transition: background 0.15s, color 0.15s, box-shadow 0.15s; }
.pr-seg button.active { background: var(--pr-card); color: var(--ink); box-shadow: 0 1px 4px rgba(36, 31, 31, 0.12); }
.payroll-inactive { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: #6b625a; cursor: pointer; }
.payroll-rates { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 14px; }
.payroll-rates > label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; font-weight: 600; color: #6b625a; }
.pr-money { display: inline-flex; align-items: center; height: 40px; border: 1px solid var(--line); border-radius: 10px; background: var(--pr-card); overflow: hidden; transition: border-color 0.15s, box-shadow 0.15s; }
.pr-money:focus-within { border-color: var(--navy); box-shadow: 0 0 0 3px rgba(22, 33, 62, 0.08); }
.pr-money i { font-style: normal; font-size: 13px; color: #9a9088; padding: 0 2px 0 10px; }
.pr-money input { border: none; outline: none; background: transparent; height: 100%; width: 118px; padding: 0 10px 0 4px; font: inherit; font-size: 16px; color: var(--ink); font-variant-numeric: tabular-nums; }
.pr-money input::placeholder { color: #b3aaa0; font-size: 13px; }
.payroll-rates-hint { margin: 12px 0 0; font-size: 13px; color: #8a8078; line-height: 1.5; }

/* 표 위 도구 줄 */
.payroll-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px; }
.payroll-photo-btn { cursor: pointer; }
.pr-legend { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-left: auto; font-size: 12px; color: #8a8078; }
.pr-legend span { margin-right: 6px; }
.pr-dot { display: inline-block; width: 10px; height: 10px; border-radius: 3px; }
.pr-dot.is-read { background: #dbe8f6; border: 1px solid #9fc0e3; }
.pr-dot.is-unclear { background: var(--pr-amber-bg); border: 1px solid var(--pr-amber); }
.pr-dot.is-hand { background: rgba(181, 35, 44, 0.12); border: 1px solid var(--pr-red); }
.payroll-photo-msg { font-size: 14px; margin: 0 0 10px; padding: 10px 14px; border-radius: 12px; background: rgba(31, 138, 76, 0.08); border: 1px solid rgba(31, 138, 76, 0.2); line-height: 1.55; }
.payroll-photo-msg.is-bad { background: rgba(181, 35, 44, 0.07); border-color: rgba(181, 35, 44, 0.25); color: var(--pr-red); font-weight: 700; }
.payroll-photo-msg div + div { margin-top: 3px; }
.payroll-status { font-size: 13px; color: #8a8078; }
.payroll-status.is-dirty { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px; background: rgba(181, 35, 44, 0.08); color: var(--pr-red); font-weight: 700; }

/* 날짜 표 */
.payroll-grid-wrap { overflow-x: auto; max-width: 100%; background: var(--pr-card); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 1px 2px rgba(36, 31, 31, 0.04); }
.payroll-grid { border-collapse: separate; border-spacing: 0; font-size: 14px; min-width: 760px; width: 100%; }
.payroll-grid th, .payroll-grid td { border-bottom: 1px solid #efe9df; padding: 3px 4px; text-align: center; }
.payroll-grid th { position: sticky; top: 0; z-index: 1; padding: 10px 4px; font-size: 13px; font-weight: 700; color: #6b625a; background: #faf7f1; border-bottom: 1px solid var(--line); }
.payroll-grid thead th:first-child { border-top-left-radius: 14px; }
.payroll-grid thead th:last-child { border-top-right-radius: 14px; }
.payroll-grid tbody tr:last-child td { border-bottom: none; }
.payroll-grid tbody tr:hover td { background: #fcfaf6; }
.payroll-grid td.pg-day { font-weight: 700; white-space: nowrap; width: 56px; color: var(--ink); }
.payroll-grid td.pg-day small { font-weight: 500; color: #a29890; margin-left: 4px; font-size: 12px; }
.payroll-grid tr.is-weekend td.pg-day small { color: var(--pr-red); }
.payroll-grid input.pg-star { width: 18px; height: 18px; accent-color: #d63031; cursor: pointer; }
.payroll-grid input.pg-t { width: 66px; height: 32px; padding: 0 2px; border: 1px solid transparent; border-radius: 8px; text-align: center; font-size: 15px; font-family: inherit; background: transparent; color: var(--ink); font-variant-numeric: tabular-nums; transition: border-color 0.15s, background 0.15s; }
.payroll-grid input.pg-t::placeholder { color: #d7d0c5; }
.payroll-grid input.pg-t:hover { border-color: #e6dfd3; }
.payroll-grid input.pg-t:focus { border-color: var(--navy); background: #fff; outline: none; box-shadow: 0 0 0 3px rgba(22, 33, 62, 0.08); }
.payroll-grid input.pg-t.is-bad { border-color: var(--pr-red); background: rgba(181, 35, 44, 0.06); }
.payroll-grid input.pg-t.is-read { color: var(--pr-blue); font-weight: 600; }
.payroll-grid input.pg-t.is-unclear { border-color: var(--pr-amber); background: var(--pr-amber-bg); }
/* 손글씨 칸 — 읽지 않았다. 직접 채워 넣어야 한다. */
.payroll-grid input.pg-t.is-hand { border: 2px solid var(--pr-red); background: rgba(181, 35, 44, 0.08); }
.payroll-grid input.pg-t.is-hand::placeholder { color: var(--pr-red); opacity: 1; }
.payroll-grid tr.is-star td { background: rgba(214, 48, 49, 0.05); }
.payroll-grid tr.is-star td.pg-day { box-shadow: inset 3px 0 0 #e17070; }
.payroll-grid tr.is-holiday td { background: rgba(230, 160, 20, 0.10); }
.payroll-grid td.pg-day .pg-tag { display: block; margin: 2px 0 0; font-size: 11px; font-weight: 700; color: #b26a00; }
.payroll-grid tr.is-closed td.pg-day .pg-tag { color: #6b7a8c; }
.payroll-holidays { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 10px 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--pr-card); }
.payroll-holidays .pr-hol-title { font-weight: 700; }
.payroll-holidays .pr-hol-list { display: flex; flex-wrap: wrap; gap: 6px; }
.payroll-holidays .pr-hol-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 10px; border-radius: 999px; background: #fff3dc; color: #7a4b00; font-size: 13px; font-weight: 600; }
.payroll-holidays .pr-hol-chip button { width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; background: rgba(0,0,0,0.06); cursor: pointer; }
.payroll-holidays .pr-hol-empty { color: #8a8078; font-size: 13px; }
.payroll-holidays .pr-hol-add { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-left: auto; }
.payroll-holidays input { height: 34px; padding: 0 8px; border: 1px solid var(--line); border-radius: 8px; font: inherit; background: var(--pr-card); color: var(--ink); }
.payroll-holidays #payrollHolidayNote { width: 130px; }
.payroll-grid td.pg-ot { white-space: nowrap; min-width: 160px; transition: background 0.15s; }
.payroll-grid tr.is-check td.pg-ot { background: var(--pr-amber-bg); }
.payroll-grid td.pg-ot b { display: inline-block; min-width: 34px; font-size: 15px; font-variant-numeric: tabular-nums; }
.payroll-grid td.pg-ot button { width: 28px; height: 28px; padding: 0; border: 1px solid var(--line); border-radius: 8px; background: var(--pr-card); color: var(--ink); font-size: 15px; cursor: pointer; transition: background 0.15s; }
.payroll-grid td.pg-ot button:hover { background: #f6f1e8; }
.payroll-grid td.pg-ot button.pg-ok { margin-left: 4px; color: #9a9088; }
.payroll-grid td.pg-ot button.pg-ok.is-on { background: var(--pr-green); color: #fff; border-color: var(--pr-green); }
.payroll-grid td.pg-ot small { display: block; margin-top: 2px; font-size: 11px; color: #8a8078; }
.payroll-grid td.pg-le { white-space: nowrap; font-size: 12px; color: #b4532a; min-width: 90px; }
.payroll-grid td.pg-le .pg-le-what { display: block; }
.payroll-grid td.pg-le .pg-le-ctl { display: inline-flex; align-items: center; gap: 4px; margin-top: 3px; color: var(--ink); }
.payroll-grid td.pg-le .pg-le-ctl b { min-width: 40px; text-align: center; font-size: 13px; color: #b4532a; }
.payroll-grid td.pg-le button { height: 26px; min-width: 26px; padding: 0 6px; border: 1px solid var(--line); border-radius: 8px; background: var(--pr-card); color: var(--ink); font-size: 13px; cursor: pointer; }
.payroll-grid td.pg-le button.pg-le-excuse { color: #1a7a43; border-color: #bfe0cb; }
.payroll-grid td.pg-le small { display: block; margin-top: 2px; font-size: 11px; color: #8a8078; }
.payroll-grid td.pg-le.is-excused .pg-le-ctl b { color: #1a7a43; }

/* 오른쪽: 이 달 지급액 · 보너스 · 저장. 넓으면 표 오른쪽에 붙어 스크롤을 따라온다. */
.payroll-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); gap: 18px 24px; align-items: start; }
.pr-main { min-width: 0; }
.payroll-side { position: sticky; top: 72px; /* 위 메뉴줄(58px, sticky) 아래 */ padding: 18px; display: flex; flex-direction: column; gap: 16px; }
.payroll-result { font-size: 15px; }
.payroll-result .pr-total { display: flex; flex-direction: column; gap: 2px; padding: 0 0 14px; margin-bottom: 10px; border-bottom: 1px solid #efe9df; }
.payroll-result .pr-total span:first-child { font-size: 13px; font-weight: 600; color: #8a8078; }
.payroll-result .pr-total span:last-child { font-size: 32px; font-weight: 800; letter-spacing: -0.5px; color: var(--ink); font-variant-numeric: tabular-nums; }
.payroll-result .pr-days { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.payroll-result .pr-days span { padding: 4px 10px; border-radius: 999px; background: var(--pr-soft); font-size: 13px; font-weight: 600; color: #5d554e; }
.payroll-result .pr-line { display: flex; justify-content: space-between; gap: 10px; padding: 7px 0; font-size: 14px; color: #4a433d; border-bottom: 1px dashed #ece5d9; }
.payroll-result .pr-line span:last-child { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); }
.payroll-result .pr-warn { font-size: 13px; color: var(--pr-red); font-weight: 600; margin: 0 0 8px; padding: 8px 10px; border-radius: 10px; background: rgba(181, 35, 44, 0.06); }
.payroll-bonus { display: flex; flex-direction: column; gap: 8px; padding: 14px; border-radius: 12px; background: #fdf8ec; border: 1px solid #f1e3bf; }
.payroll-bonus label { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-weight: 700; font-size: 14px; }
.payroll-bonus .pr-money input { width: 120px; }
.payroll-bonus #payrollBonusNote { height: 38px; padding: 0 12px; border: 1px solid #ecdcb3; border-radius: 10px; background: #fff; font: inherit; font-size: 14px; color: var(--ink); }
.pr-save { display: flex; flex-direction: column; align-items: stretch; gap: 8px; text-align: center; }
.payroll-rules, .payroll-help { margin-top: 18px; font-size: 14px; color: #6b625a; }
/* 근무 규칙은 맨 위 — 한 줄 요약이 곧 여는 손잡이(2026-10-04). */
.pr-rules-top { margin: 0 0 10px; }
.pr-rules-top > summary { list-style: none; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pr-rules-top > summary::-webkit-details-marker { display: none; }
.pr-rules-top .pr-rules-gear { font-weight: 700; color: var(--ink); }
.pr-rules-top .payroll-hours { margin: 0; }
.pr-rules-top .pr-rules-edit { padding: 4px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--pr-card); color: var(--ink); font-size: 13px; font-weight: 600; }
.pr-rules-top .pr-rules-edit::after { content: " ▾"; }
.pr-rules-top[open] .pr-rules-edit::after { content: " ▴"; }
.pr-rules-top[open] .payroll-rules-form { padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--pr-card); }
.payroll-rules summary, .payroll-help summary { cursor: pointer; font-weight: 600; }
.payroll-rules-form { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 10px; }
.payroll-rules-form input { height: 38px; width: 80px; padding: 0 10px; border: 1px solid var(--line); border-radius: 10px; font: inherit; background: var(--pr-card); color: var(--ink); }
.payroll-rules-form input#payrollWorkHours { width: 220px; }
.payroll-result .pr-line.pr-deduct span:last-child { color: #b4532a; }
/* 표(최소 760px)와 오른쪽 칸이 같이 들어가지 않으면 결과를 표 아래로 내린다. */
@media (max-width: 1180px) {
  .payroll-body { grid-template-columns: minmax(0, 1fr); }
  .payroll-side { position: static; }
}
@media (max-width: 600px) {
  .pr-name { width: 100%; }
  .pr-legend { margin-left: 0; }
  .payroll-rates > label, .pr-money, .pr-money input { width: 100%; }
  .payroll-bonus label { flex-direction: column; align-items: stretch; }
  .payroll-bonus .pr-money input { width: 100%; }
}
.payroll-rates > label[hidden] { display: none; }

/* 급여 「한눈에 보기」(2026-10-03) — 결산의 큰 숫자·막대·그래프를 그대로 빌려 쓴다. */
.payroll-overview { margin: 6px 0 18px; }
.payroll-overview .stl-hero, .payroll-overview .settlement-charts-grid, .payroll-overview .settlement-wide-card { max-width: none; }
.payroll-overview .settlement-charts-grid { margin-bottom: 16px; }
.pr-ov-bars .stl-bar-row { cursor: pointer; }
.pr-ov-bars .stl-bar-row:hover .stl-bar-name { text-decoration: underline; }
.pr-ov-bars .is-nocard .stl-bar-name { color: var(--muted); }
.pr-ov-table-wrap { overflow-x: auto; }
.pr-ov-table { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.pr-ov-table th { text-align: right; font-weight: 600; color: var(--muted); padding: 8px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.pr-ov-table td { text-align: right; padding: 9px 10px; border-bottom: 1px solid #f0ebe2; white-space: nowrap; }
.pr-ov-table th:first-child, .pr-ov-table td:first-child { text-align: left; }
.pr-ov-table tbody tr { cursor: pointer; }
.pr-ov-table tbody tr:hover td { background: #faf6ef; }
.pr-ov-table td.is-total { font-weight: 800; }
.pr-ov-table td .pr-ov-warn { color: #b26a00; font-weight: 700; }
.pr-ov-table td .pr-ov-minus { color: #b4532a; }
.pr-ov-table tr.is-nocard td { color: var(--muted); }
.pr-ov-table td.pr-ov-nocard { text-align: left; }
.pr-ov-table tfoot td { font-weight: 800; border-top: 2px solid var(--line); border-bottom: 0; }
.payroll-overview .pr-ov-note { margin: 12px 0 0; font-size: 13px; }
/* 지각·조퇴 막대는 차감 색 — 돈이 빠지는 쪽이라 지급액 막대(남색)와 갈라 읽힌다. */
.pr-ov-late .stl-bar-fill { background: #b4532a; }
.pr-ov-late { grid-template-columns: minmax(88px, 220px) 1fr minmax(96px, max-content) minmax(44px, max-content); }

/* 급여·결산 잠금 창(2026-10-04) */
.pin-gate-title { font-weight: 700; font-size: 17px; margin: 0 0 12px; }
.pin-gate input { width: 100%; box-sizing: border-box; height: 46px; padding: 0 12px; border: 1px solid var(--line); border-radius: 10px; font: inherit; font-size: 18px; letter-spacing: 0.1em; }
.pin-gate-error { color: #b5232c; font-size: 14px; margin: 8px 0 0; }

/* 급여 — 카드 사진 끌어다 놓기(2026-10-04). 끌고 들어오면 탭 전체에 점선 테두리와 안내. */
#tab-payroll { position: relative; }
#tab-payroll.is-dropping::after {
  content: attr(data-drop-label);
  position: absolute; inset: 0; z-index: 30;
  display: flex; align-items: flex-start; justify-content: center; padding-top: 120px;
  border: 3px dashed var(--navy); border-radius: 16px;
  background: rgba(22, 33, 62, 0.08);
  font-size: 22px; font-weight: 800; color: var(--navy);
  pointer-events: none;
}

/* 급여 카드 옮기기 창(2026-10-04) */
.pr-move label { display: flex; flex-direction: column; gap: 6px; margin: 0 0 12px; font-size: 14px; font-weight: 600; }
.pr-move input, .pr-move select { height: 44px; padding: 0 10px; border: 1px solid var(--line); border-radius: 10px; font: inherit; font-size: 16px; }

/* 마지막 저장·고침 시각(2026-10-04) */
.payroll-saved-at { display: block; width: 100%; margin-top: 6px; font-size: 12.5px; color: #6b625a; line-height: 1.5; }
.payroll-saved-at b { color: var(--ink); font-weight: 700; }
.payroll-saved-at .is-dirty-at { color: #b5232c; }
.pr-ov-table td.pr-ov-saved { color: #6b625a; font-size: 13px; }
.payroll-photo-msg .pm-warn { color: var(--pr-red); font-weight: 700; }

/* ───────── 식자재 탭 (2026-10-04) ─────────
   「무엇을 · 얼마에 · 몇 개 샀나」. 결산 탭과 같은 뼈대를 쓴다 — 두 화면이
   다른 모양이면 사장님이 매번 눈을 다시 맞춰야 한다. */
.ing-shell { padding: 4px 2px 40px; }
.ing-toolbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin-bottom: 10px; }
.ing-field { display: flex; flex-direction: column; gap: 3px; font-size: 14px; color: var(--muted); }
.ing-field select, .ing-field input {
  padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; background: #fff;
}
.ing-toolbar button {
  padding: 8px 12px; border: 1px solid var(--line); border-radius: 8px; background: #fff;
  font-size: 15px; cursor: pointer;
}
.ing-toolbar button:hover { background: var(--cream); }
/* 가져오기 단추는 오른쪽 끝으로 민다 — 날마다 쓰는 것이 아니라 가끔 쓰는 것이다. */
.ing-spacer { flex: 1 1 auto; }
.ing-note { color: var(--muted); font-size: 14px; margin: 4px 0 10px; }
.ing-import-log {
  margin: 0 0 12px; padding: 9px 12px; border-radius: 8px;
  background: var(--cream); border: 1px solid var(--line); font-size: 14.5px;
}

.ing-hero { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; margin-bottom: 14px; }
.ing-hero-label { color: var(--muted); font-size: 14px; }
.ing-hero-value { font-size: 34px; font-weight: 800; line-height: 1.2; }
.ing-hero-sub { color: var(--muted); font-size: 14px; }

/* 한눈에 보기 — 결산·급여와 같은 모양(2026-10-06 사장님: "급여처럼 저런 전체
   보기로 결산 보는 것처럼"). 큰 숫자·카드·그래프·표는 결산 것을 그대로 쓰고,
   여기엔 식자재에만 있는 것(업체 칩 줄·내역 표)만 적는다. */
/* 월·연을 볼 때는 하루 결산을 **감춘다**(쌓지 않고 바꾼다).
   도구 줄과 월·연 카드만 남긴다 — 어느 블록이 하루 것인지 일일이 적지 않아도
   되게 「그 둘이 아닌 것」으로 적는다. */
.settlement-content.is-period > *:not(.settlement-toolbar):not(#settlementPeriod):not(.stl-loading) { display: none !important; }
.settlement-mode { margin-right: 6px; }

/* 월 결산 · 연 결산 (2026-10-06). 매출 − 식자재 − 인건비 = 남은 것 을
   **한 줄로** 둬서 빼는 셈이 눈에 보이게 한다. 좁으면 두 줄로 접힌다. */
.stl-period { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; margin-bottom: 14px; }
.stl-period-head { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; justify-content: space-between; }
.stl-period-head h3 { margin: 0; font-size: 17px; }
.stl-period-pick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.stl-period-pick input, .stl-period-pick select { font: inherit; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; }
.stl-period-pick button { height: 34px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; background: #fff; cursor: pointer; font: inherit; }
.stl-period-pick button:hover { background: #faf6ef; }
.stl-period-pick .pr-seg button.is-on { background: var(--navy, #16213e); color: #fff; border-color: var(--navy, #16213e); }
.stl-period-space { flex: 1 1 auto; }
.stl-period-note { margin: 10px 0 0; color: var(--muted); font-size: 14px; }
.stl-period-note.is-warn { color: #b4541f; font-weight: 600; }
.stl-period-calc {
  display: grid; grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr;
  align-items: center; gap: 10px; margin: 14px 0 6px;
}
.stl-period-cell { background: #faf7f1; border-radius: 12px; padding: 12px 14px; min-width: 0; }
.stl-period-cell.is-revenue { background: #16213e; color: #fff; }
.stl-period-cell.is-left { background: #e8f0e6; }
.stl-period-cell.is-left.is-minus { background: #f6e3e3; }
.stl-period-label { display: block; font-size: 13px; opacity: 0.75; }
.stl-period-cell strong { display: block; font-size: clamp(20px, 2.4vw, 30px); font-weight: 800; line-height: 1.25; font-variant-numeric: tabular-nums; }
.stl-period-sub { display: block; font-size: 12.5px; opacity: 0.7; }
.stl-period-op { font-size: 22px; font-weight: 700; color: var(--muted); text-align: center; }
.stl-period-year { margin-top: 14px; display: grid; gap: 14px; }
.stl-period-year .settlement-chart-wrap { height: 260px; }
/* 지난 정산 추이는 날마다 막대 하나 — 낮아도 읽힌다. */
.settlement-history-card .settlement-chart-wrap { height: 200px; }
.ing-ov-table td.is-minus { color: #b4541f; }
@media (max-width: 900px) {
  .stl-period-calc { grid-template-columns: 1fr auto 1fr; }
  .stl-period-calc .stl-period-op:nth-of-type(2) { display: none; }
}

.ing-overview { margin-bottom: 14px; }

/* 영수증 대기함 — 올린 사진이 읽히기를 기다리는 자리(2026-10-06). */
.ing-inbox-tools { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.ing-inbox-count {
  padding: 3px 10px; border-radius: 999px; background: #fdecea;
  font-size: 13px; font-weight: 700; color: var(--red, #b5232c);
}
.ing-inbox-count:empty { display: none; }
/* 이미 장부에 있는 영수증 — 손대기 전에 보여야 한다(2026-10-17). */
.ing-have {
  margin: 0 0 12px; padding: 10px 14px; border-radius: 10px;
  background: #fff6d8; border: 1px solid #e8b100; color: #6b5200; font-size: 14.5px;
}
.ing-check-have {
  background: #e8b100; color: #fff; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; padding: 1px 7px;
}
/* 제목 옆에 「무엇을」 — 어느 영수증을 보고 있는지(2026-10-17). */
.ing-entry-which { margin-left: 10px; font-size: 14px; font-weight: 600; color: var(--muted); }
/* 대기함은 접어 둔다 — 확인하러 들어와서 여덟 층을 지나지 않게(2026-10-17). */
.ing-inbox-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.ing-inbox-head .ing-inbox-tools { margin: 0 0 0 auto; gap: 8px; }
/* 「사진 올리기 · 전부 받기 · 한꺼번에 넣기」 — 예전엔 브라우저 기본 단추(회색 작은 네모) 그대로였다
   (2026-10-18 사장님: "사진 올리기 이런 버튼도 너무 구리고"). */
.ing-inbox-tools > button {
  display: inline-flex; align-items: center; gap: 6px; height: 38px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 10px; background: #fff; color: #2f3542;
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.ing-inbox-tools > button:hover { border-color: #cfc5b6; box-shadow: 0 2px 8px rgba(36, 31, 31, 0.08); }
.ing-inbox-tools > button.primary { background: #2f3542; border-color: #2f3542; color: #fff; }
.ing-inbox-tools > button.primary:hover { background: #3d4555; }
.ing-inbox-tools > button:disabled { opacity: 0.55; cursor: default; box-shadow: none; }
/* 눌러서 펴는 머리(2026-10-18 사장님: "눌러서 볼 수 있는 거라고 알기가 어려워" → 테두리·빨간 알약을
   달았더니 "너무 구식 같아"). 위의 「장부 / 영수증 확인」 칸과 같은 말투로: 장수는 옅은 배지, 끝에 둥근
   ⌄ 단추, 마우스를 올리면 머리 전체가 옅게 칠해진다. */
.ing-fold {
  display: flex; align-items: center; gap: 10px; margin: -6px 0 -6px -8px;
  border: none; border-radius: 12px; background: transparent; padding: 6px 8px;
  cursor: pointer; font: inherit; color: inherit; text-align: left;
  transition: background 0.15s;
}
.ing-fold:hover { background: #f5f1ea; }
.ing-fold-title { font-weight: 700; }
.ing-fold-mark { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; font-weight: 600; }
.ing-fold-chev {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%; background: #efe9df; color: #2f3542;
  transition: transform 0.2s, background 0.15s;
}
.ing-fold:hover .ing-fold-chev { background: #2f3542; color: #fff; }
.ing-fold.is-open .ing-fold-chev { transform: rotate(180deg); }
.ing-fold-body { margin-top: 10px; }
/* 식자재 안의 두 칸 — 장부(홈)와 영수증 확인(2026-10-17). */
.ing-views { display: flex; gap: 8px; margin: 0 0 14px; }
.ing-view-tab {
  border: 1px solid var(--line); background: #fff; border-radius: 10px;
  padding: 8px 16px; cursor: pointer; font: inherit; font-size: 15px; font-weight: 600; color: var(--muted);
}
.ing-view-tab:hover { box-shadow: 0 2px 8px rgba(36, 31, 31, 0.08); }
.ing-view-tab.is-on { background: #2f3542; border-color: #2f3542; color: #fff; }
.ing-view-tab.has-work:not(.is-on) { border-color: #e8b100; color: #8a6a00; }
/* 저장한 영수증 되돌리기(2026-10-18) */
.ing-inbox-btn.is-undo { color: #b4541f; border-color: #e8d7d7; }
/* 확인하기 / 직접 넣기 — 둘 중 하나(2026-10-18 사장님: "손으로 넣는거나 직접 넣는게 같이 있는 게 조금 불편해"). */
.ing-entry-modes { display: flex; gap: 8px; margin: 0 0 14px; }
.ing-entry-mode-btn {
  border: 1px solid var(--line); background: #fff; border-radius: 10px; min-height: 44px;
  padding: 8px 18px; cursor: pointer; font: inherit; font-size: 16px; font-weight: 700; color: var(--muted);
}
.ing-entry-mode-btn.is-on { background: #2f3542; border-color: #2f3542; color: #fff; }
.ing-mode-n { margin-left: 4px; color: #e8b100; }
.ing-entry-mode-btn.is-on .ing-mode-n { color: #ffd54a; }
.ing-check-empty { margin: 8px 0 4px; padding: 18px; border: 1px dashed var(--line); border-radius: 10px; color: var(--muted); font-size: 15px; text-align: center; }
/* 영수증마다 칩 — 급여의 직원 칩과 같은 쓰임(2026-10-17). 102장이라 옆으로 구른다. */
.ing-check-bar { margin: 0 0 12px; }
.ing-check-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.ing-step {
  border: 1px solid var(--line); background: #fff; border-radius: 10px;
  padding: 10px 22px; cursor: pointer; font: inherit; font-size: 16px; font-weight: 700;
  min-height: 44px;                       /* 패드로 누르는 단추다 */
}
.ing-step:hover { box-shadow: 0 2px 8px rgba(36, 31, 31, 0.1); }
.ing-step:active { background: #f1f1f4; }
.ing-check-at { display: flex; align-items: baseline; gap: 6px; font-size: 14px; color: var(--muted); }
.ing-check-at b { font-size: 19px; color: var(--ink); font-variant-numeric: tabular-nums; }
/* 「어떤 건 이미 올라가 있고 어떤 건 새로 들어가나」 — 숫자를 누르면 그것만 남는다
   (2026-10-19). 「저장됨」은 칩이 아니라 대기함의 그 칸으로 보낸다. */
.ing-check-filters { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.ing-check-filter {
  border: 1px solid var(--line); background: #fff; border-radius: 999px;
  padding: 6px 12px; cursor: pointer; font: inherit; font-size: 13.5px; color: var(--muted);
  min-height: 34px;
}
.ing-check-filter b { color: var(--ink, #241f1f); font-variant-numeric: tabular-nums; }
.ing-check-filter.is-on { background: var(--cream, #faf7f1); border-color: #c9b89a; color: var(--ink, #241f1f); font-weight: 700; }
.ing-check-filter[disabled] { opacity: 0.45; cursor: default; }
.ing-check-filter.is-saved { border-style: dashed; }
.ing-check-none { color: var(--muted); font-size: 13.5px; padding: 4px 2px; }
/* 칩은 옆으로 구르지 않고 **줄을 바꿔** 다 보인다(2026-10-21 사장님: "드래그하면서 찾지 않고 바로 보여지게").
   많으면 다섯 줄쯤에서 칸 안으로 내려간다 — 표가 화면 밖으로 밀리지 않게. 위 업체 칸으로 좁히면 몇 장 안 된다. */
.ing-check-chips {
  display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 4px;
  max-height: 196px; overflow-y: auto; scrollbar-width: thin;
}
/* 위 칸: 왼쪽은 ◀ 이전 · 다음 ▶ 과 거르개, 오른쪽 빈 자리에 업체가 한눈에. */
.ing-check-top { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 18px; align-items: start; margin-bottom: 10px; }
.ing-check-left .ing-check-filters { margin-bottom: 0; }
.ing-check-vendors { min-width: 0; }
.ing-check-vendors-title { font-size: 12.5px; color: var(--muted); margin: 2px 0 6px; }
.ing-check-vendors-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.ing-check-vendor {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 36px;
  border: 1px solid var(--line); background: #fff; border-radius: 10px; padding: 6px 10px;
  cursor: pointer; font: inherit; font-size: 13.5px; color: var(--ink, #241f1f); text-align: left;
}
.ing-check-vendor:hover { border-color: #cfc5b6; box-shadow: 0 2px 8px rgba(36, 31, 31, 0.08); }
.ing-check-vendor-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ing-check-vendor b { font-variant-numeric: tabular-nums; color: var(--muted); font-size: 12.5px; }
.ing-check-vendor.is-on { background: #2f3542; border-color: #2f3542; color: #fff; }
.ing-check-vendor.is-on b { color: #ffd54a; }
.ing-check-vendor.is-none { border-style: dashed; }
@media (max-width: 900px) { .ing-check-top { grid-template-columns: 1fr; } }
.ing-check-chip {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  border: 1px solid var(--line); background: #fff; border-radius: 999px;
  padding: 5px 12px; cursor: pointer; font-size: 13.5px; color: var(--ink);
}
.ing-check-chip:hover { box-shadow: 0 2px 8px rgba(36, 31, 31, 0.08); }
.ing-check-chip.is-on { background: #2f3542; border-color: #2f3542; color: #fff; }
.ing-check-day { color: var(--muted); font-variant-numeric: tabular-nums; }
.ing-check-store { color: var(--muted); font-size: 12px; }
.ing-check-chip.is-on .ing-check-store { color: #cfd6e4; }
.ing-check-chip.is-on .ing-check-day { color: #cfd6e4; }
.ing-check-warn {
  background: #e8b100; color: #fff; border-radius: 999px;
  min-width: 18px; text-align: center; font-size: 12px; font-weight: 700; padding: 0 5px;
}
/* 확인할 줄의 단추는 눈에 띄게, 표는 열릴 때 잠깐 테를 두른다(2026-10-17). */
.ing-inbox-btn.is-go { background: #2f3542; border-color: #2f3542; color: #fff; font-weight: 700; }
.ing-entry.is-just-filled { animation: ing-just-filled 2s ease-out 1; border-radius: 12px; }
@keyframes ing-just-filled {
  0% { box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.55); }
  100% { box-shadow: 0 0 0 3px rgba(192, 57, 43, 0); }
}
/* 상태별 칸 — 「확인 대기」만 따로 보려고(2026-10-17). */
.ing-inbox-tabs { display: flex; gap: 6px; margin: 0 0 10px; flex-wrap: wrap; }
.ing-inbox-tab {
  border: 1px solid var(--line); background: #fff; border-radius: 999px;
  padding: 4px 12px; cursor: pointer; font-size: 13.5px; color: var(--muted);
}
.ing-inbox-tab b { font-variant-numeric: tabular-nums; margin-left: 4px; }
.ing-inbox-tab.is-on { background: #2f3542; border-color: #2f3542; color: #fff; }
.ing-inbox-list { display: flex; flex-direction: column; gap: 8px; max-height: 420px; overflow-y: auto; }
.ing-inbox-row {
  display: grid; grid-template-columns: 56px 1fr auto; align-items: center; gap: 12px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: #fff;
}
.ing-inbox-row.is-on { border-color: var(--navy, #16213e); box-shadow: 0 0 0 2px rgba(22, 33, 62, 0.12); }
.ing-inbox-thumb { width: 56px; height: 56px; object-fit: cover; border-radius: 8px; background: #f1ece3; }
.ing-inbox-thumb.is-gone { display: block; }
.ing-inbox-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; min-width: 0; }
.ing-inbox-meta strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 320px; }
.ing-inbox-when { color: var(--muted); font-size: 13px; }
.ing-inbox-read { color: var(--muted); font-size: 13px; }
.ing-inbox-badge { font-size: 12.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: #f1ece3; }
.ing-inbox-badge.is-read { background: #fdf3d6; }
.ing-inbox-badge.is-saved { background: #e4efe4; }
.ing-inbox-acts { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.ing-inbox-btn {
  height: 32px; padding: 0 10px; display: inline-flex; align-items: center; border-radius: 8px;
  border: 1px solid var(--line); background: #fff; color: var(--ink); cursor: pointer; font: inherit; font-size: 13.5px; text-decoration: none;
}
.ing-inbox-btn:hover { background: #faf6ef; }
.ing-inbox-btn.is-del { border-color: #e8d7d7; }
/* 한꺼번에 넣기 — 115장을 줄마다 붙여넣지 않아도 되게(2026-10-17). */
.ing-inbox-many { display: grid; gap: 8px; margin: 0 0 12px; }
.ing-inbox-many textarea { width: 100%; box-sizing: border-box; font: inherit; font-size: 13px; padding: 8px; border: 1px solid var(--line); border-radius: 8px; resize: vertical; }
.ing-inbox-many-tools { display: flex; gap: 8px; }
.ing-inbox-paste { grid-column: 1 / -1; display: flex; gap: 8px; align-items: flex-start; }
.ing-inbox-paste textarea { flex: 1 1 auto; font: inherit; font-size: 13.5px; padding: 8px; border: 1px solid var(--line); border-radius: 8px; resize: vertical; }

/* 사진은 표 **옆에** 둔다 — 숫자만 보고는 맞는지 알 수 없다. 화면을 굴려도
   따라오게 붙여 둔다(sticky). 좁은 화면에서는 위아래로 내려간다. */
.ing-entry-split { display: block; }
.ing-entry.has-photo .ing-entry-split { display: grid; grid-template-columns: minmax(240px, 0.8fr) 2fr; gap: 14px; align-items: start; }
.ing-entry-photo { position: sticky; top: 12px; }
.ing-entry-photo img { width: 100%; border-radius: 10px; border: 1px solid var(--line); background: #faf7f1; }
.ing-entry-photo-tools { display: flex; gap: 8px; margin-top: 6px; font-size: 13.5px; }
.ing-entry-photo-tools a, .ing-entry-photo-tools button {
  border: 1px solid var(--line); background: #fff; border-radius: 8px; padding: 4px 10px; cursor: pointer; color: var(--ink); text-decoration: none; font: inherit; font-size: 13.5px;
}
@media (max-width: 900px) {
  .ing-entry.has-photo .ing-entry-split { grid-template-columns: 1fr; }
  .ing-entry-photo { position: static; }
  .ing-entry-photo img { max-height: 340px; object-fit: contain; }
}
/* 막대 **묶음 전체가 하나의 격자**다(결산 .stl-bars 와 같은 이유) — 줄마다
   제 격자를 쓰면 이름 칸 너비가 줄마다 달라져서 막대 시작이 어긋나고,
   그러면 서로 견줄 수가 없다. 줄은 display:contents 로 칸만 내어준다. */
.ing-bars {
  display: grid;
  grid-template-columns: minmax(88px, 260px) 1fr minmax(96px, max-content) minmax(40px, max-content);
  align-items: center; column-gap: 10px; row-gap: 9px;
}
.ing-bars .ing-bar { display: contents; }
.ing-bars .ing-bar.clickable:hover > * { background: #faf7f1; }
.ing-bars .ing-bar-value { text-align: right; font-weight: 700; white-space: nowrap; }
.ing-bars .ing-bar-sub { text-align: right; color: var(--muted); font-size: 13.5px; white-space: nowrap; }
.ing-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 14px; }
.ing-chip {
  height: 34px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; color: var(--ink); cursor: pointer; font: inherit; font-size: 14px; font-weight: 600;
  max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ing-chip:hover { box-shadow: 0 2px 8px rgba(36, 31, 31, 0.08); }
.ing-chip.is-on { background: var(--navy, #16213e); color: #fff; border-color: var(--navy, #16213e); }

.ing-ov-table-wrap { overflow-x: auto; }
.ing-ov-table { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.ing-ov-table th { text-align: right; font-weight: 600; color: var(--muted); padding: 8px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.ing-ov-table td { text-align: right; padding: 9px 10px; border-bottom: 1px solid #f0ebe2; white-space: nowrap; }
.ing-ov-table th:first-child, .ing-ov-table td:first-child { text-align: left; }
.ing-ov-table td.is-total { font-weight: 800; }
.ing-ov-table tbody tr[data-ing-vendor] { cursor: pointer; }
.ing-ov-table tbody tr:hover td { background: #faf6ef; }
.ing-ov-table tbody tr.is-on td { background: #f3efe6; font-weight: 700; }
/* 산 내역은 줄이 많다 — 길어지면 그 안에서 굴린다. 품목 이름만 왼쪽. */
.ing-rows-table td.is-name, .ing-rows-table th:nth-child(2) { text-align: left; }
.ing-rows-table tbody tr { cursor: default; }
.ing-ov-table-wrap { max-height: 520px; overflow-y: auto; }

.ing-block { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; margin-bottom: 14px; }
.ing-block-title { margin: 0 0 10px; font-size: 17px; }
/* 업체와 품목을 나란히 — 둘을 같이 보는 일이 많다. 좁으면 한 줄로 내려간다. */
.ing-two { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 900px) { .ing-two { grid-template-columns: 1fr; } }

/* 한 줄 = 이름 · 막대 · 금액 · 작은 글씨. 결산의 막대와 같은 모양이다. */
.ing-bar {
  display: grid; grid-template-columns: minmax(90px, 1.4fr) minmax(60px, 2fr) auto auto;
  align-items: center; gap: 8px; padding: 5px 2px; font-size: 14.5px;
}
.ing-bar.clickable { cursor: pointer; border-radius: 6px; }
.ing-bar.clickable:hover { background: #faf7f1; }
.ing-bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ing-bar-track { background: var(--cream); border-radius: 999px; height: 10px; overflow: hidden; }
.ing-bar-fill { height: 100%; background: var(--brand, #c0392b); opacity: .8; }
.ing-bar-value { text-align: right; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ing-bar-sub { text-align: right; color: var(--muted); font-size: 13px; white-space: nowrap; min-width: 54px; }

/* 단가 추이 — 선 하나. 높이를 못 박아 둔다(viewBox 가 늘어나면 점이 뭉갠다). */
.ing-price-chart { margin: 4px 0 10px; }
.ing-price-chart svg { width: 100%; height: 140px; display: block; }
.ing-rows { display: flex; flex-direction: column; }
.ing-row {
  display: grid; grid-template-columns: 96px 1fr auto auto; gap: 10px;
  padding: 5px 2px; border-top: 1px solid var(--line); font-size: 14.5px;
  font-variant-numeric: tabular-nums;
}
.ing-row:first-child { border-top: none; }

/* 영수증 넣기 — 식자재 탭의 주 작업이다.
   2026-10-04 사장님: "종이를 보면서 엑셀에 기입하고 하는 과정이 너무 귀찮아서." */
.ing-entry-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin-bottom: 8px; }
.ing-field-wide { flex: 1 1 220px; }
.ing-field-wide input { width: 100%; }
.ing-entry-head input, .ing-entry-head select {
  padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px; font-size: 16px; background: #fff;
}
.ing-entry-head button {
  padding: 8px 14px; border: 1px solid var(--line); border-radius: 8px; background: #fff; font-size: 15px; cursor: pointer;
}
.ing-entry-head button.primary { background: var(--brand, #c0392b); color: #fff; border-color: transparent; }

/* 한 줄 = 번호 · 품목 · 수량 · 단위 · 단가 · 금액 · 지우기. 경고는 그 아래 한 줄.
   번호(2026-10-29 사장님: "앞에 칸 한개 만들어서 숫자 넣어줄래?") — 종이의 序號와 줄을 맞춰 보게. */
.ing-line {
  display: grid; grid-template-columns: 26px minmax(130px, 2.2fr) 80px 70px 90px 100px 34px;
  gap: 6px; align-items: center; padding: 3px 0;
}
.ing-line-head { color: var(--muted); font-size: 13px; padding-bottom: 2px; }
/* 둘째 전표가 시작하는 줄 — 번호가 1로 돌아가는 자리에 금을 긋는다 */
.ing-line.is-slip-start { border-top: 2px dashed #c9bfae; margin-top: 8px; padding-top: 9px; }
.ing-line-no { text-align: center; font-size: 15px; font-weight: 800; color: #4a4a4a; font-variant-numeric: tabular-nums; }
.ing-line input {
  width: 100%; padding: 6px 7px; border: 1px solid var(--line); border-radius: 7px;
  font-size: 15px; font-variant-numeric: tabular-nums;
}
/* 금액은 거의 늘 저절로 나온다 — 쳐야 하는 칸이 아니라는 것이 보이게 연하게. */
.ing-in-amount { background: #faf7f1; font-weight: 700; }
.ing-x { border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 16px; }
.ing-x:hover { color: var(--brand, #c0392b); }
/* 경고 줄은 품목 칸 아래로 들여쓴다 — 어느 줄의 말인지 보이게. */
.ing-line-warn { grid-column: 1 / -1; padding: 0 0 4px 4px; font-size: 13px; min-height: 0; }
.ing-warn { color: #b9770e; background: #fdf3df; border-radius: 999px; padding: 1px 8px; margin-right: 6px; }
.ing-hint { color: var(--muted); margin-right: 6px; }
.ing-new { color: #1e7e34; background: #e8f5ec; border-radius: 999px; padding: 1px 8px; }
.ing-add-line {
  margin-top: 6px; padding: 6px 12px; border: 1px dashed var(--line); border-radius: 8px;
  background: #fff; cursor: pointer; font-size: 14.5px; color: var(--muted);
}
.ing-add-line:hover { background: var(--cream); }
.ing-entry-foot {
  display: flex; justify-content: flex-end; align-items: baseline; gap: 10px;
  margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); font-size: 16px;
}
.ing-entry-foot strong { font-size: 20px; font-variant-numeric: tabular-nums; }
@media (max-width: 720px) {
  .ing-line { grid-template-columns: 22px 1fr 64px 56px 76px 86px 30px; }
  .ing-line input { font-size: 14px; padding: 5px; }
}

/* 영수증 사진에서 잘라낸 칸 그림. 숫자 바로 밑에 붙여 **눈으로 맞춰** 보신다.
   숫자 하나를 88% 로 읽으니 세 자리 금액은 68% 다 — 종이를 다시 찾아 줄을
   짚는 것보다 그림을 한 번 보는 것이 빠르다(2026-10-05). */
.ing-pic { display: block; max-width: 100%; height: 26px; margin-top: 3px; border: 1px solid #ddd; border-radius: 3px; background: #fff; }
/* 확실치 않은 줄. 「틀린 값을 표시 없이 넣지 않는다」가 기준이다. */
.ing-strip-bar {
  display: flex; align-items: center; gap: 6px; padding: 4px 2px 6px;
  font-size: 13px; color: var(--muted);
}
.ing-strip-bar button {
  border: 1px solid var(--line); background: #fff; border-radius: 6px;
  padding: 1px 8px; cursor: pointer; font-size: 13px; line-height: 1.6;
}
.ing-strip-off { min-width: 22px; text-align: center; font-variant-numeric: tabular-nums; }
/* 사진의 그 줄 — 숫자 바로 밑에(2026-10-17). 종이를 다시 찾지 않게. */
.ing-line-strip { grid-column: 1 / -1; padding: 1px 0 5px 2px; }
.ing-line-strip img {
  display: block; max-width: 100%; height: auto; border: 1px solid var(--line);
  border-radius: 4px; background: #fff;
}
.ing-line-unsure { background: #fff8d8; border-left: 3px solid #e8b100; }
/* 마지막 줄 **바로 밑** 한 줄(2026-10-18 사장님: "총 8개인데 품목은 7개 밖에 없어").
   글씨가 보이면 한 줄이 빠진 것이다 — 숫자만 봐서는 영영 안 보인다. */
.ing-after-strip {
  margin-top: 6px; padding: 6px 8px; border: 1px dashed var(--line); border-radius: 8px;
  background: #fcfbf7; font-size: 13px; color: var(--muted);
}
.ing-after-strip img { display: block; max-width: 100%; height: auto; margin-top: 4px; border: 1px solid var(--line); border-radius: 4px; background: #fff; }
/* 사진을 끌어다 놓는 동안 */
.ing-drop { outline: 3px dashed #4a90d9; outline-offset: -6px; }

/* 지난 주문의 「반품·취소」 — 인쇄·미리보기와 **다른 일**이라 색으로 가른다
   (2026-10-07: 정산 뒤에는 실시간 주문판에서 할 수 없어서 여기에 뒀다). */
.stl-order-btn.stl-order-refund { color: #b4541f; border-color: #e8d7d7; }
.stl-order-btn.stl-order-refund:hover { background: #fdf3ef; }
.stl-order-btn.stl-order-unpay { color: #b3261e; border-color: #f0c9c6; }
.stl-order-btn.stl-order-unpay:hover { background: #fdeceb; }

/* 지난 주문을 **날짜로 접는다**(2026-10-07 사장님: "너무 아래로 길게 뻗어나가서
   한 참전에 건 정말 오래 걸려"). 한 달을 봐도 줄이 서른 개다. 목록 자체도
   제 안에서 굴러서 페이지가 아래로 안 늘어난다. */
/* 440 — 위(.stl-orders 첫 정의)와 같은 값. 560 으로 두었더니 결산 화면이 그만큼 길어져
   e2e-settlement-ui.js(2,600) · e2e-order-history.js(목록 500) 상한을 넘었다(2026-10-18). */
.stl-orders { max-height: 440px; overflow-y: auto; }
.stl-day { border: 1px solid var(--line); border-radius: 10px; margin-bottom: 8px; background: #fff; }
.stl-day-head {
  display: grid; grid-template-columns: 18px minmax(96px, auto) 1fr auto; align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px; border: 0; background: none; cursor: pointer; font: inherit; text-align: left;
}
.stl-day-head:hover { background: #faf6ef; border-radius: 10px; }
.stl-day.is-open .stl-day-head { border-bottom: 1px solid var(--line); border-radius: 10px 10px 0 0; }
.stl-day-date { font-weight: 700; font-variant-numeric: tabular-nums; }
.stl-day-sub { color: var(--muted); font-size: 13.5px; }
.stl-day-total { font-weight: 700; font-variant-numeric: tabular-nums; }
.stl-day-body { padding: 4px 8px 8px; }

/* 돌려줄 품목 고르기 — 줄마다 「전부」 한 번이면 그 품목을 다 고른다
   (2026-10-07 사장님: "특정 메뉴만 선택해서 취소할 수 있게도 해줘"). */
.refund-pick-hint { margin: 0 0 8px; color: var(--muted); font-size: 13.5px; text-align: center; }
.refund-step .refund-all {
  margin-left: 6px; height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px;
  background: #fff; cursor: pointer; font: inherit; font-size: 13px; color: var(--ink);
  /* 좁은 창에서 「전부」가 「전/부」로 쪼개졌다 — 한 줄로 못 박는다 */
  white-space: nowrap; flex: 0 0 auto;
}
.refund-step .refund-all:hover { background: #faf6ef; }

/* 영수증 부가세 5%(2026-10-21) — 영수증마다 셋 중 하나. 위 「영수증 확인 / 직접 넣기」 칸과 같은 말투. */
.ing-vat { margin-top: 12px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: #fcfaf6; }
.ing-vat-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ing-vat-title { font-weight: 800; font-size: 15px; }
.ing-vat-remember { font-size: 13px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.ing-vat-opts, .ing-inbox-vat { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 10px; }
.ing-vat-opt {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 10px 12px;
  border: 1.5px solid var(--line); border-radius: 10px; background: #fff; color: #2f3542; cursor: pointer; text-align: left;
}
.ing-vat-opt b { font-size: 15px; }
.ing-vat-opt small { font-size: 12px; color: var(--muted); line-height: 1.35; }
.ing-vat-opt:hover { border-color: #cfc5b6; }
.ing-vat-opt.is-on { border-color: #2f3542; background: #2f3542; color: #fff; }
.ing-vat-amt { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-top: 8px; font-size: 14px; }
.ing-vat-amt-label { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; }
.ing-vat-amt input { width: 110px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; font-size: 15px; font-weight: 700; text-align: right; }
.ing-vat-amt.is-edited input { border-color: #c98a1a; background: #fff8e8; }
.ing-vat-amt-auto { padding: 5px 10px; border: 1px solid var(--line); border-radius: 8px; background: #fff; font-size: 13px; cursor: pointer; }
.ing-vat-amt-hint { font-size: 13px; color: var(--muted); }
.ing-vat-amt-hint.is-warn { color: #b3261e; font-weight: 700; }
.ing-vat-opt.is-on small { color: #d9dde4; }
.ing-vat-note { margin: 10px 0 0; font-size: 14px; font-weight: 600; color: #2f3542; }
.ing-vat-note.is-warn { color: #8a6a00; }
.ing-inbox-vat { grid-column: 1 / -1; }
.ing-vat-chip {
  margin-left: 6px; padding: 2px 10px; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; font-size: 12px; font-weight: 700; color: #2f3542; cursor: pointer;
}
.ing-vat-chip.is-unset { background: #fff6d6; border-color: #e8b100; color: #8a6a00; }
.ing-vat-chip.is-add { background: #e4eef8; border-color: #b9cfe6; color: #1f4e79; }
@media (max-width: 600px) { .ing-vat-opts, .ing-inbox-vat { grid-template-columns: 1fr; } }

/* ── 영수증 확인을 덜 빽빽하게(2026-10-21 사장님: "UI 좀 더 깔끔하게 해줄래? 지금 잡다한 게 너무 많아서
   꽉차보여서 불편해") ──
   · 확인하기에서는 직접 넣을 때만 쓰는 📷 단추·안내 글을 접는다(.is-checking — renderEntryMode)
   · 거르개·업체·칩은 테두리 없는 옅은 알약으로 — 선이 수십 개 겹치던 것이 꽉 차 보이게 한 주범이었다
   · 0장인 거르개는 아예 안 그린다
   · 부가세는 카드 셋이 아니라 한 줄짜리 고르개로(설명은 단추에 올리면 보인다) */
.ing-entry.is-checking #ingPhotoBtn,
.ing-entry.is-checking #ingEntryHint,
.ing-entry.is-checking [data-i18n="ingPhotoHint"] { display: none; }
.ing-check-filters { gap: 4px; }
.ing-check-filter {
  border: none; background: transparent; padding: 5px 10px; min-height: 30px; font-size: 13px; border-radius: 8px;
}
.ing-check-filter:hover { background: #f3efe8; }
.ing-check-filter.is-on { background: #2f3542; color: #fff; font-weight: 700; }
.ing-check-filter.is-on b { color: #ffd54a; }
.ing-check-filter[disabled] { display: none; }
.ing-check-filter.is-saved { border: none; color: var(--muted); }
.ing-check-vendors-title { font-size: 12px; margin: 0 0 6px; }
.ing-check-vendors-grid { display: flex; flex-wrap: wrap; gap: 4px; }
.ing-check-vendor {
  border: none; background: #f5f2ec; border-radius: 8px; min-height: 30px; padding: 4px 10px; gap: 6px; font-size: 13px;
}
.ing-check-vendor:hover { background: #ebe5da; box-shadow: none; border: none; }
.ing-check-vendor b { font-size: 12px; font-weight: 600; }
.ing-check-vendor.is-none { border: none; color: var(--muted); }
.ing-check-chips { gap: 4px; max-height: 118px; padding-top: 2px; }
.ing-check-chip { border: none; background: #f5f2ec; padding: 4px 10px; font-size: 13px; gap: 5px; }
.ing-check-chip:hover { background: #ebe5da; box-shadow: none; }
.ing-check-chip.is-on { background: #2f3542; }
.ing-check-store { font-size: 11.5px; }
.ing-check-top { gap: 24px; margin-bottom: 8px; }
.ing-vat { margin-top: 10px; padding: 10px 12px; background: transparent; }
.ing-vat-head { justify-content: flex-start; gap: 12px; }
.ing-vat-opts { display: inline-flex; gap: 0; margin: 0; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.ing-vat-opt {
  flex-direction: row; align-items: center; border: none; border-radius: 0; padding: 7px 14px;
  font-size: 14px; font-weight: 700; background: #fff;
}
.ing-vat-opt + .ing-vat-opt { border-left: 1px solid var(--line); }
.ing-vat-opt:hover { background: #f5f2ec; border-color: var(--line); }
.ing-vat-opt.is-on { background: #2f3542; color: #fff; }
.ing-vat-remember { margin-left: auto; }
.ing-vat-note { margin-top: 8px; font-size: 13px; font-weight: 600; }
.ing-inbox-vat { display: flex; gap: 0; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; width: max-content; max-width: 100%; }
.ing-inbox-vat[hidden] { display: none; }
@media (max-width: 600px) {
  .ing-vat-opts { display: flex; width: 100%; }
  .ing-vat-opt { flex: 1; justify-content: center; padding: 8px 6px; }
  .ing-vat-remember { margin-left: 0; }
}

/* ── 업체마다 한 줄(2026-10-21 사장님: "너무 지저분하게 나열되어있어") ──
   업체 칸과 칩 구름을 따로 두던 것을 한 덩어리로: 줄 머리(업체 · 몇 장) + 날짜순 영수증.
   넓은 화면에서는 두 단으로 흘러서 한눈에 들어온다. 많으면 그 칸 안에서 내려간다. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.ing-check-top { display: flex; align-items: center; gap: 12px 20px; flex-wrap: wrap; margin-bottom: 10px; }
.ing-check-left { display: flex; align-items: center; gap: 12px 20px; flex-wrap: wrap; }
.ing-check-left .ing-check-head { margin-bottom: 0; }
.ing-check-chips {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(460px, 1fr)); gap: 0 28px;
  max-height: 252px; overflow-y: auto; padding: 2px 2px 4px; flex-wrap: nowrap;
  border-top: 1px solid var(--line);
}
.ing-check-row {
  display: grid; grid-template-columns: 168px minmax(0, 1fr); gap: 10px; align-items: start;
  padding: 6px 0; border-bottom: 1px solid #f0ebe2;
}
.ing-check-row .ing-check-vendor {
  width: 100%; justify-content: space-between; background: transparent; padding: 4px 8px; min-height: 30px; font-weight: 700;
}
.ing-check-row .ing-check-vendor:hover { background: #f3efe8; }
.ing-check-row .ing-check-vendor.is-on { background: #2f3542; color: #fff; }
.ing-check-vendor-x { font-size: 11px; opacity: 0.8; }
.ing-check-dates { display: flex; flex-wrap: wrap; gap: 4px; padding-top: 1px; }
.ing-check-dates .ing-check-chip { padding: 4px 9px; font-size: 13px; }
.ing-check-dates .ing-check-day { color: var(--ink, #241f1f); font-weight: 600; }
.ing-check-dates .ing-check-chip.is-on .ing-check-day { color: #fff; }
.ing-check-dates .ing-check-name { color: var(--muted); font-size: 12px; }
@media (max-width: 700px) {
  .ing-check-chips { grid-template-columns: 1fr; }
  .ing-check-row { grid-template-columns: 120px minmax(0, 1fr); }
}
