/*
 * app.css — 관람객 화면(트랙 E) 공용 스타일
 *
 * **다크 전용이다** (docs/DESIGN.md 0절). `prefers-color-scheme` 분기와
 * `[data-theme]` 스탬프를 쓰지 않는다. 색은 전부 tokens.css 에서 온다 —
 * 이 파일에 하드코딩된 hex 를 남기지 않는다.
 *
 * 모바일 우선(기준 375px, 최소 320px). 데스크톱(≥768px)은 가운데 480px 고정
 * 컬럼 + 배치도만 720px까지(DESIGN.md 5절).
 */

@import url('tokens.css');

/* ── 기본 ─────────────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: var(--fw-body);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  word-break: keep-all;
  overflow-wrap: anywhere;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; line-height: var(--lh-title); text-wrap: balance; }
h1 { font-size: var(--fs-title); font-weight: var(--fw-title); letter-spacing: var(--ls-title); }
h2 { font-size: var(--fs-section); font-weight: var(--fw-section); letter-spacing: var(--ls-section); }
h3 { font-size: var(--fs-body); font-weight: 700; }
p { margin: 0 0 0.7em; }
p:last-child { margin-bottom: 0; }
a { color: var(--brand-soft); text-underline-offset: 3px; }

:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: 4px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 8px; top: -60px;
  z-index: 100;
  padding: 10px 14px;
  background: var(--brand-soft);
  color: var(--brand-ink);
  border-radius: var(--r-btn);
  text-decoration: none;
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: 8px; }

[hidden] { display: none !important; }

/* ── 레이아웃 ─────────────────────────────────────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.topbar__inner {
  max-width: 960px;
  margin: 0 auto;
  padding: 10px var(--gutter);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 56px;
}

.brand {
  font-weight: 700;
  font-size: var(--fs-sub);
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

/*
 * 워드마크 이미지. 흰색 아트워크라 어두운 헤더에 그대로 얹는다.
 * 비율(4.23:1)은 width/height 속성으로 브라우저에 미리 알려 줘 로드 중 레이아웃이
 * 밀리지 않게 하고, 높이만 지정해 폭은 비율대로 따라오게 둔다.
 */
.brand__logo {
  display: block;
  height: 22px;
  width: auto;
  flex: none;
  /* 로고는 흰색 단색이다. 밝은 지면에서는 tokens.css 가 반전을 넘겨 준다.
     여기서 테마를 분기하지 않는다 — 값은 토큰 한 곳에서만 정해진다. */
  filter: var(--logo-filter, none);
}

.topbar__nav {
  margin-left: auto;
  display: flex;
  gap: var(--sp-1);
}

.topbar__nav a {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-btn);
  font-size: var(--fs-sub);
  color: var(--ink-2);
  text-decoration: none;
  min-height: var(--tap-min);
  display: inline-flex;
  align-items: center;
}
.topbar__nav a:hover { background: var(--surface-2); color: var(--ink); }
.topbar__nav a[aria-current='page'] { color: var(--ink); font-weight: 700; background: var(--surface-2); }

.wrap {
  max-width: 960px;
  margin: 0 auto;
  padding: var(--gutter) var(--gutter) 110px;
}

.wrap--narrow { max-width: 640px; }

.stack > * + * { margin-top: var(--sp-3); }
.stack-lg > * + * { margin-top: var(--sp-5); }

.site-footer {
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: var(--fs-caption);
  padding: var(--sp-5) var(--gutter) 40px;
  text-align: center;
}

.muted { color: var(--ink-2); }
.small { font-size: var(--fs-sub); }
.tiny { font-size: var(--fs-caption); }
.num { font-family: var(--font-num); font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }
.center { text-align: center; }

/* ── 카드 ─────────────────────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--sp-4);
}

.card--pad-lg { padding: var(--sp-5); }

.card__title {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}

.card__title h2 { font-size: var(--fs-section); }

/* ── 히어로 (행사 안내) ───────────────────────────────────────────────────── */

/* ── 행사 카드 (행사 안내 화면) ──────────────────────────────────────────────
 *
 * 사진 에셋이 없으므로 히어로는 그라디언트로 만든다.
 * 남산 야경 + 루프탑 스트링 조명을 층으로 쌓았다. 나중에 실제 사진이 생기면
 * .ev-hero 에 --ev-photo 로 넘기면 그라디언트 위에 얹힌다.
 */
.ev-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}

.ev-hero {
  position: relative;
  aspect-ratio: 16 / 10;
  background:
    var(--ev-photo, none) center / cover no-repeat,
    /* 스트링 조명 */
    radial-gradient(2.5px 2.5px at 12% 26%, rgba(255, 214, 150, 0.95), transparent 60%),
    radial-gradient(2px 2px at 27% 21%, rgba(255, 214, 150, 0.8), transparent 60%),
    radial-gradient(2.5px 2.5px at 41% 27%, rgba(255, 214, 150, 0.9), transparent 60%),
    radial-gradient(2px 2px at 56% 20%, rgba(255, 214, 150, 0.75), transparent 60%),
    radial-gradient(2.5px 2.5px at 71% 26%, rgba(255, 214, 150, 0.9), transparent 60%),
    radial-gradient(2px 2px at 86% 22%, rgba(255, 214, 150, 0.8), transparent 60%),
    /* 지평선 불빛 */
    radial-gradient(120% 55% at 50% 108%, rgba(255, 168, 92, 0.22), transparent 62%),
    radial-gradient(70% 50% at 82% 88%, rgba(231, 26, 15, 0.16), transparent 70%),
    /* 밤하늘 */
    linear-gradient(180deg, #101722 0%, #16202e 42%, #1b1a1e 78%, #171417 100%);
}

/* 아래쪽을 살짝 어둡게 — 뱃지와 카드 본문 경계가 뜬다 */
.ev-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 12, 16, 0.45) 0%, transparent 34%, rgba(10, 12, 16, 0.5) 100%);
}

.ev-hero__top {
  position: absolute;
  inset: var(--sp-3) var(--sp-3) auto;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-2);
}

.ev-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 12px;
  border-radius: var(--r-chip);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.ev-pill--live { background: var(--brand); color: #fff; }
.ev-pill--live::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
}
.ev-pill--closed { background: var(--dim); color: #fff; }
.ev-pill--soon { background: var(--warn); color: #241a06; }
.ev-pill--venue {
  background: rgba(12, 14, 18, 0.66);
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
 * 행사 목록 (index.html)
 *
 * 목록 항목이 곧 위의 .ev-card 다 — 예매 버튼까지 그대로 달려 있어 목록에서
 * 바로 좌석 선택으로 들어간다. 여기서는 카드를 세로로 쌓기만 한다.
 * ------------------------------------------------------------------------- */
.ev-list__title {
  font-size: var(--fs-title);
  font-weight: var(--fw-title);
  letter-spacing: var(--ls-title);
  margin: 0 0 var(--sp-4);
}

/* 카드 자체는 상세 화면과 같은 .ev-card 를 그대로 쓴다. 목록은 그것을 세로로
   쌓기만 한다 — 목록용 카드 디자인을 따로 만들면 두 화면이 서서히 어긋난다. */
.ev-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-5); }
.ev-list > li { margin: 0; }

.ev-list__empty {
  padding: var(--sp-5) var(--sp-4);
  text-align: center;
  color: var(--ink-2);
  border: 1px dashed var(--line-2);
  border-radius: var(--r-card);
}

/* 끝난 행사(마감 · 매진)는 목록에 남기되 — 예매 내역을 확인하러 오는 사람이 있다 —
   눈에 덜 띄게 한다. 아직 열리지 않은 '오픈 예정' 은 여기 해당하지 않는다. */
.ev-item--muted .ev-card { opacity: 0.62; }
.ev-item--muted .ev-hero { filter: grayscale(1); }

.ev-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
}

.ev-title {
  font-size: 22px;
  font-weight: 800;
  line-height: 1.32;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0;
}

.ev-desc {
  margin: 0;
  color: var(--ink-2);
  font-size: 14px;
  line-height: 1.6;
}

.ev-facts {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 13px 14px;
  border-radius: 12px;
  background: var(--surface-2);
}

.ev-fact {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  line-height: 1.5;
}
.ev-fact svg {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  color: var(--ink-3);
}

.ev-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-top: var(--sp-1);
}

.ev-price__label {
  font-size: 12px;
  color: var(--ink-3);
  margin-bottom: 2px;
}
.ev-price__val {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.ev-price__val small { font-size: 15px; font-weight: 700; margin-left: 2px; }

.ev-foot .btn { flex: 1 1 auto; max-width: 300px; }

/* 좁은 화면에서는 가격 위, 버튼 아래 */
@media (max-width: 479px) {
  .ev-foot { flex-direction: column; align-items: stretch; }
  .ev-foot .btn { max-width: none; }
}

.hero {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--sp-5) var(--sp-4);
}

.hero__eyebrow {
  font-size: var(--fs-caption);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--brand-soft);
  text-transform: uppercase;
  margin-bottom: var(--sp-2);
}

.hero h1 { font-size: var(--fs-title); margin-bottom: var(--sp-3); }

.hero__meta {
  display: grid;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}

.meta-row {
  display: grid;
  grid-template-columns: 68px 1fr;
  gap: var(--sp-3);
  align-items: start;
  font-size: var(--fs-body);
}

.meta-row dt { color: var(--ink-2); font-size: var(--fs-sub); padding-top: 1px; }
.meta-row dd { margin: 0; }

/* ── 카운트다운 ───────────────────────────────────────────────────────────── */

.countdown {
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  border-radius: var(--r-card);
  background: var(--surface-2);
  border: 1px solid var(--line);
  text-align: center;
}

.countdown__label {
  font-size: var(--fs-sub);
  color: var(--ink-2);
  margin-bottom: var(--sp-2);
}

.countdown__clock {
  display: flex;
  justify-content: center;
  gap: var(--sp-2);
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
}

.cd-unit {
  min-width: 58px;
  padding: var(--sp-2) 6px;
  border-radius: var(--r-btn);
  background: var(--surface);
  border: 1px solid var(--line);
}

.cd-unit b { display: block; font-size: 2rem; font-weight: 700; line-height: 1.2; }
.cd-unit span { font-size: var(--fs-caption); color: var(--ink-2); font-family: var(--font); }

.countdown.is-open {
  background: var(--ok-soft);
  border-color: var(--ok);
  color: var(--ok);
}
.countdown.is-open .countdown__label { color: inherit; font-weight: 700; font-size: var(--fs-body); }

/* ── 인원수 선택 (좌석 화면 상단) ─────────────────────────────────────────── */

.party-pick {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.party-pick__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2);
}
.party-pick__head h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.party-pick__hint { font-size: var(--fs-caption); color: var(--ink-3); }

/* ── 결제 방법 선택 ───────────────────────────────────────────────────────── */

.pay-pick { border: none; padding: 0; margin: 0; }
.pay-pick legend { padding: 0; margin-bottom: var(--sp-2); }

.pay-opts { display: grid; gap: var(--sp-2); }
@media (min-width: 400px) { .pay-opts { grid-template-columns: 1fr 1fr; } }

.pay-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 14px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  background: var(--surface-2);
  cursor: pointer;
}
.pay-opt input { accent-color: var(--brand); width: 18px; height: 18px; flex: none; }
.pay-opt__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pay-opt__name { font-size: 15px; font-weight: 600; }
.pay-opt__desc { font-size: var(--fs-caption); color: var(--ink-3); }
.pay-opt:has(input:checked) { border-color: var(--brand); background: var(--surface-3); }
.pay-opt:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }

.aside-btn {
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-chip);
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.aside-btn:hover { background: var(--surface-2); color: var(--ink); }

/* ── 바텀시트 dialog ──────────────────────────────────────────────────────── */

dialog.sheet {
  width: min(100%, 480px);
  max-height: 86vh;
  margin: auto auto 0;
  padding: 0;
  border: none;
  border-radius: var(--r-sheet);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--sh-float);
  overflow: hidden;
}
dialog.sheet::backdrop { background: rgba(8, 10, 12, 0.62); }

.sheet__grip {
  width: 36px;
  height: 4px;
  margin: 10px auto 2px;
  border-radius: 999px;
  background: var(--line-2);
}

.sheet__body {
  padding: var(--sp-3) var(--sp-4) var(--sp-2);
  overflow-y: auto;
  max-height: calc(86vh - 116px);
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}

.sheet__title { font-size: 19px; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
.sheet__section { display: flex; flex-direction: column; gap: var(--sp-2); }
.sheet__label {
  margin: 0;
  font-size: var(--fs-caption);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}

.sheet__warn {
  margin: 0;
  padding: 12px 14px;
  border-radius: var(--r-btn);
  background: var(--warn-soft);
  border-left: 3px solid var(--warn);
  color: var(--warn);
  font-size: 13.5px;
  line-height: 1.6;
}
.sheet__warn b { color: inherit; font-weight: 700; }

.sheet__foot {
  padding: var(--sp-3) var(--sp-4) max(var(--sp-4), env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
  background: var(--surface);
}

@media (prefers-reduced-motion: no-preference) {
  dialog.sheet[open] { animation: sheet-up 0.18s cubic-bezier(0.2, 0.8, 0.2, 1); }
  @keyframes sheet-up { from { transform: translateY(14px); opacity: 0; } }
}

/* ── 가격표 ───────────────────────────────────────────────────────────────── */

.price-list { display: grid; gap: var(--sp-2); }

.price-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface);
}

.price-row__swatch {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1px solid var(--line-2);
  flex: none;
}

.price-row__label { font-weight: 700; }
.price-row__code { font-size: var(--fs-caption); color: var(--ink-2); margin-left: 4px; }
.price-row__price {
  margin-left: auto;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-num);
}

/* ── 칩 (인원수) ──────────────────────────────────────────────────────────── */

.chip-row {
  display: flex;
  gap: var(--sp-2);
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.chip-row::-webkit-scrollbar { display: none; }

.chip {
  appearance: none;
  flex: none;
  scroll-snap-align: start;
  height: 40px;
  padding: 0 18px;
  border-radius: var(--r-chip);
  border: none;
  background: var(--surface-2);
  color: var(--ink-2);
  font: inherit;
  font-weight: 600;
  font-size: var(--fs-sub);
  cursor: pointer;
  min-width: var(--tap-min);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.chip.is-active {
  background: var(--ink);
  color: var(--bg);
}

/* ── 버튼 ─────────────────────────────────────────────────────────────────── */

.btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 12px 18px;
  border-radius: var(--r-btn);
  border: 1px solid var(--line-2);
  background: var(--surface-2);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-btn);
  font-weight: var(--fw-btn);
  letter-spacing: var(--ls-btn);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
  touch-action: manipulation;
}

.btn:hover { background: var(--surface-3); }
.btn:active { transform: scale(.99); }

/* primary — 화면당 하나 (DESIGN 2·6절) */
/*
 * 주 액션은 채운 빨강이다. 흰 글자와의 대비가 4.61:1 로 본문 기준(4.5:1)을 넘는다.
 * --brand 를 "글자색" 으로 쓸 때만 대비가 모자란 것이지(3.6:1) 채움에는 해당이 없다.
 */
.btn--primary {
  height: 52px;
  border: none;
  background: var(--brand);
  color: #fff;
  font-weight: 700;
}
.btn--primary:hover { background: var(--brand-hover); }
.btn--primary:active { background: var(--brand-dim); }

/* outlined — 보조 */
.btn--outlined { border: 1px solid var(--line-2); background: transparent; color: var(--ink); }
.btn--outlined:hover { background: var(--surface-2); }

/* danger — 파괴적 액션. 채우지 않는다 */
.btn--danger { border: 1px solid var(--danger); background: transparent; color: var(--danger-text); }
.btn--danger:hover { background: var(--danger-soft); }

.btn--ghost { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn--ghost:hover { background: var(--surface-2); }

.btn--block { width: 100%; }
.btn--sm { min-height: var(--tap-min); padding: 8px 14px; font-size: var(--fs-sub); }

.btn[disabled],
.btn[aria-disabled='true'] {
  background: var(--surface-3);
  color: var(--ink-3);
  border-color: transparent;
  cursor: not-allowed;
  pointer-events: none;
}

.btn.is-busy { position: relative; color: transparent; }
.btn.is-busy::after {
  content: '';
  position: absolute;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  color: var(--brand-ink);
  animation: spin 0.7s linear infinite;
}
.btn--ghost.is-busy::after,
.btn--danger.is-busy::after,
.btn--outlined.is-busy::after { color: var(--ink-2); }

@keyframes spin { to { transform: rotate(360deg); } }

.btn-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.btn-row .btn { flex: 1 1 auto; }

/* ── 폼 ───────────────────────────────────────────────────────────────────── */

.field { display: block; margin-bottom: var(--sp-4); }

.field__label {
  display: block;
  font-size: var(--fs-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  margin-bottom: var(--sp-2);
  color: var(--ink-3);
}

.field__label .req { color: var(--brand); margin-left: 2px; }

.field__hint { font-size: var(--fs-caption); color: var(--ink-3); margin-top: var(--sp-2); }

.input {
  width: 100%;
  min-height: 52px;
  padding: 12px 14px;
  border: none;
  border-radius: var(--r-btn);
  background: var(--surface-2);
  color: var(--ink);
  font: inherit;
  font-size: 1rem; /* iOS 확대 방지 */
}

.input::placeholder { color: var(--ink-3); opacity: 1; }
.input:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.input[aria-invalid='true'] { outline: 2px solid var(--danger); outline-offset: 0; }

.field__error {
  display: none;
  margin-top: var(--sp-2);
  font-size: var(--fs-caption);
  color: var(--danger-text);
  font-weight: 600;
}
.field__error:not(:empty) { display: block; }

.checkline {
  display: flex;
  gap: var(--sp-2);
  align-items: flex-start;
  font-size: var(--fs-sub);
  color: var(--ink-2);
  cursor: pointer;
  padding: var(--sp-1) 0;
}
.checkline input { width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--brand); flex: none; }

/* ── 알림 · 토스트 ────────────────────────────────────────────────────────── */

.alert {
  display: flex;
  gap: var(--sp-2);
  align-items: flex-start;
  /* sticky 헤더 바로 아래에 붙어 나오면 눌린 느낌이라 위아래로 숨통을 준다 */
  margin: var(--sp-3) 0;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-card);
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: var(--fs-sub);
  line-height: 1.5;
}

.alert:empty { display: none; }
.alert__icon { flex: none; font-weight: 800; }
.alert--error { background: var(--danger-soft); border-color: var(--danger); color: var(--danger-text); }
.alert--warn { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }
.alert--ok { background: var(--ok-soft); border-color: var(--ok); color: var(--ok); }
.alert--info { background: var(--info-soft); border-color: var(--info); color: var(--info-ink); }

.toast-stack {
  position: fixed;
  left: 50%;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 80;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  width: min(92vw, 420px);
  pointer-events: none;
}

.toast {
  background: var(--surface-3);
  color: var(--ink);
  border-radius: var(--r-btn);
  padding: 12px 16px;
  font-size: var(--fs-sub);
  box-shadow: var(--sh-pop);
  text-align: center;
}

@media (prefers-reduced-motion: no-preference) {
  .toast { animation: toast-in var(--dur) var(--ease) both; }
  @keyframes toast-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
  }
}

/* ── 스텝 표시 ────────────────────────────────────────────────────────────── */

.steps {
  list-style: none;
  margin: 0 0 var(--sp-4);
  padding: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-caption);
  color: var(--ink-3);
  overflow-x: auto;
  scrollbar-width: none;
}
.steps::-webkit-scrollbar { display: none; }

.steps__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: var(--r-chip);
  background: var(--surface-2);
  border: 1px solid transparent;
  white-space: nowrap;
}

.steps__item b {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--line-2);
  color: var(--surface);
  font-size: 0.68rem;
  display: grid;
  place-items: center;
  flex: none;
}

.steps__item.is-current {
  background: var(--surface-3);
  color: var(--ink);
  font-weight: 700;
}
.steps__item.is-current b { background: var(--ink); color: var(--bg); }
.steps__item.is-done { color: var(--ink-2); }
.steps__item.is-done b { background: var(--ok); color: var(--bg); }

.steps__sep { color: var(--line-2); flex: none; }

/* ── 예매 플로우 전용 헤더 (booking.html) ─────────────────────────────────── */

.flow-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  height: 56px;
  padding: 0 var(--sp-2) 0 var(--sp-1);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.flow-header__back {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--ink);
  width: var(--tap-min);
  height: var(--tap-min);
  border-radius: 50%;
  font-size: 1.4rem;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: none;
}
.flow-header__back:hover { background: var(--surface-2); }
/*
 * 뒤로갈 곳이 없는 완료 화면 — 버튼 자리를 비워 두지 않는다.
 * 대신 제목을 행사 안내 화면의 로고와 같은 들여쓰기(--gutter)에 맞춘다.
 * (기본 헤더의 왼쪽 패딩은 뒤로가기 버튼이 시각 여백을 만들어 주는 전제라 4px 이다)
 */
.flow-header--plain { padding-left: var(--gutter); }

.flow-header__title {
  font-size: var(--fs-section);
  font-weight: var(--fw-section);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.flow-header__aside {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.party-badge {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--ink-2);
  background: var(--surface-2);
  border-radius: var(--r-chip);
  padding: 6px 12px;
  font-variant-numeric: tabular-nums;
}

.hold-clock {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-section);
  font-weight: 700;
  color: var(--ink);
  padding: 4px 10px;
  border-radius: var(--r-chip);
  background: var(--surface-2);
}

.hold-clock.is-urgent {
  color: var(--danger-text);
  background: var(--danger-soft);
  font-weight: 800;
}

/* ── 예매 플로우 화면(main) ───────────────────────────────────────────────── */

.flow-main {
  max-width: 960px;
  margin: 0 auto;
  padding: var(--gutter) var(--gutter) 120px;
}

.flow-screen { display: flex; flex-direction: column; gap: var(--sp-4); }

.flow-title { font-size: var(--fs-title); font-weight: var(--fw-title); letter-spacing: var(--ls-title); }
.flow-sub { font-size: var(--fs-sub); color: var(--ink-3); margin-top: 2px; }

/* ── 하단 고정 바 ─────────────────────────────────────────────────────────── */

.bottom-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  background: var(--surface);
  box-shadow: var(--sh-float);
  padding: var(--sp-3) var(--gutter) max(var(--sp-3), env(safe-area-inset-bottom, 0px));
}

.bottom-bar__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}

.bottom-bar__row:only-child { margin-bottom: 0; }

.bottom-bar__label { min-width: 0; }
.bottom-bar__seats {
  font-size: var(--fs-sub);
  color: var(--ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bottom-bar__amount {
  font-size: var(--fs-amount);
  font-weight: var(--fw-amount);
  letter-spacing: var(--ls-amount);
  font-variant-numeric: tabular-nums;
  font-family: var(--font-num);
  /*
   * 금액은 절대 접지 않는다. flex 아이템은 기본으로 줄어들 수 있어서, 좁은 화면에서
   * 좌석 라벨이 길면 금액이 눌려 "1,200,000" / "원" 처럼 두 줄로 갈라진다.
   * 자리가 모자라면 줄여야 하는 쪽은 좌석 라벨이다 — 그쪽은 말줄임(…)이 걸려 있다.
   */
  flex: none;
  white-space: nowrap;
}

.bottom-bar__hint {
  text-align: center;
  color: var(--ink-3);
  font-size: var(--fs-sub);
  padding: 12px 0;
}

/* ── 인원수 화면 ──────────────────────────────────────────────────────────── */

.count-hero h1 { margin-bottom: 4px; }

/* ── 좌석 선택 (전체 배치도 · 확대 · 데스크톱) ────────────────────────────── */

.map-panel { padding: var(--sp-3); position: relative; }

.map-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--r-btn);
  background: var(--surface-2);
  padding: 6px;
  position: relative;
}

.map-scroll .seatmap {
  display: block;
  width: 100%;
  height: auto;
  /*
   * 세로 화면에서는 렌더러가 배치도를 90도 돌려(미디어월이 위로) 내용에 맞춰
   * viewBox 를 조인다. 그 결과 375px 화면에서도 테이블 타깃이 약 61px 나오므로
   * 가로 스크롤을 강제할 이유가 없다. 세로 스크롤은 모바일에서 자연스럽다.
   *
   * 가로가 넉넉한 화면에서만 원래 방향으로 그려지고, 그때는 최소 폭이 필요하다.
   */
}

@media (min-width: 768px) {
  .map-scroll .seatmap {
    min-width: 760px;
  }
}

/* 확대 뷰는 화면 폭에 그대로 맞춘다 — zoomLayout() 이 실측 폭 기준으로 좌표를 낸다. */
.seatmap--zoom.seatmap {
  min-width: 0;
}

.map-hint {
  font-size: var(--fs-caption);
  color: var(--ink-3);
  margin: var(--sp-2) 2px 0;
  display: flex;
  gap: var(--sp-2);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}

.legend-bar {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}

.legend-status {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: var(--sp-2);
  font-size: var(--fs-caption);
  color: var(--ink-3);
}

.legend-status i {
  width: 10px; height: 10px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 5px;
  vertical-align: -1px;
  border: 1px solid rgba(0, 0, 0, 0.35);
}
.legend-status .dot-taken { background: var(--dim); }

.back-to-map {
  display: block;
  margin: 0 auto;
  background: none;
  border: none;
  color: var(--ink-2);
  font-size: var(--fs-sub);
  font-weight: 600;
  padding: var(--sp-2) var(--sp-3);
  min-height: var(--tap-min);
  cursor: pointer;
}
.back-to-map:hover { color: var(--ink); }

/*
 * 잔여가 인원수보다 적은 테이블 dim 처리 (DESIGN.md 7.2).
 * renderSeatMap 은 partySize 를 모르므로 상태를 모른다 — booking.js 가 렌더 후
 * 직접 `.is-low` 클래스를 그 테이블의 <g data-group-id> 에 붙인다.
 * seatmap.css 는 건드리지 않고 여기서만 보완한다.
 */
.seatmap .sm-group.is-low .sm-table,
.seatmap .sm-group.is-low .sm-row {
  opacity: 0.45;
}
.seatmap .sm-group.is-low .sm-badge-bg { fill: var(--dim-soft); }
.seatmap .sm-group.is-low .sm-badge-text { fill: var(--ink-3); }

/* ── 미니맵 오버레이 (DESIGN.md 7.3) ──────────────────────────────────────── */


/* ── 좌석 선택 요약 ───────────────────────────────────────────────────────── */

.seat-guidance {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sub);
  color: var(--ink-2);
}

/* ── 홀드 타이머(배너형 · 정보입력 화면) ──────────────────────────────────── */

.holdbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-card);
  background: var(--warn-soft);
  border: 1px solid var(--warn);
  color: var(--warn);
  font-size: var(--fs-sub);
  font-weight: 600;
}

.holdbar > span:first-child { min-width: 0; }

.holdbar__time {
  margin-left: auto;
  flex: none;
  white-space: nowrap;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 1.15rem;
  font-weight: 800;
}

.holdbar.is-urgent {
  background: var(--danger-soft);
  border-color: var(--danger);
  color: var(--danger-text);
}

/* ── 요약 · 정의 목록 ─────────────────────────────────────────────────────── */

.kv { margin: 0; display: grid; gap: 0; }

.kv > div {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.kv > div:last-child { border-bottom: 0; }

.kv dt { color: var(--ink-3); font-size: var(--fs-sub); }
.kv dd { margin: 0; font-weight: 600; }

.total-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--sp-4);
  margin-top: var(--sp-3);
  border-radius: var(--r-card);
  background: var(--surface-2);
  border: 1px solid var(--line);
}
.total-row span { font-weight: 700; color: var(--ink-2); }
.total-row b {
  font-size: var(--fs-amount);
  font-variant-numeric: tabular-nums;
  font-family: var(--font-num);
  color: var(--ink);
}

/* ── 입금 안내 — 화면에서 가장 눈에 띄어야 한다 ───────────────────────────── */

/* ---------------------------------------------------------------------------
 * 접수 완료 화면 (booking.html #stepDone)
 *
 * 읽는 순서를 그대로 세로로 세운다 — ① 아직 안 끝났다 ② 얼마나 남았다
 * ③ 무엇을 예매했다 ④ 어디에 얼마를 넣어야 한다.
 * 아래 .paybox 는 예매 조회(lookup.html)가 쓰는 것이라 건드리지 않는다.
 * ------------------------------------------------------------------------- */
/*
 * 예매 상세 — 접수 완료 화면과 예매 조회가 같은 마크업을 쓴다 (reservation-view.js).
 * 카드가 서로 붙어 한 덩어리로 보이지 않게 흐름 간격을 준다. 값은 .flow-screen 과
 * 같은 --sp-4 라, 이 뷰가 다른 단계 사이에 끼어도 리듬이 어긋나지 않는다.
 * flex 라 hidden 카드(취소 박스 등)는 빈 간격을 남기지 않는다.
 */
/*
 * 카드 사이 24px, 제목과 제 카드 사이 8px. 3배 차이라 "제목 + 카드" 가 한 덩어리로
 * 묶여 읽히고, 덩어리끼리는 확실히 갈린다. 같은 값이면 제목이 위 카드에 붙어 보인다.
 */
.rv { display: flex; flex-direction: column; gap: var(--sp-5); }

/*
 * 카드 제목은 카드 **바깥**에 둔다. 카드는 값(계좌 · 금액 · 좌석)만 담아
 * 무엇을 읽어야 하는지가 카드 안에서 한 번 더 갈리지 않게 한다.
 * 오른쪽 상태(결제 완료 · 입금 확인 대기)는 제목과 같은 줄에 붙는다.
 */
.sec { display: flex; flex-direction: column; gap: var(--sp-2); }
.sec__head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  padding: 0 var(--sp-1);
}
.sec__title { font-size: var(--fs-section); font-weight: 700; }
.sec__state {
  margin-left: auto;
  font-size: var(--fs-caption);
  color: var(--warn);
  white-space: nowrap;
}
.sec__state--ok { color: var(--ok); }

.done-head { text-align: center; padding: var(--sp-3) 0 var(--sp-2); }

.done-head__icon {
  width: 52px;
  height: 52px;
  margin: 0 auto var(--sp-4);
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--warn-soft);
  color: var(--warn);
}
.done-head__icon svg { width: 24px; height: 24px; }

/* 확정·취소·만료는 아이콘 색으로 먼저 읽힌다 (문구는 그 아래) */
.done-head__icon--ok { background: var(--ok-soft); color: var(--ok); }
.done-head__icon--off { background: var(--dim-soft); color: var(--dim); }

.done-head__eyebrow { margin: 0 0 4px; font-size: var(--fs-sub); color: var(--ink-2); }

.done-head__note {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-sub);
  color: var(--ink-2);
  line-height: 1.55;
}

.done-head__title {
  margin: 0;
  font-size: var(--fs-title);
  font-weight: var(--fw-title);
  letter-spacing: var(--ls-title);
}

/* 남은 시간 — 이 화면에서 가장 큰 숫자다 */
.done-clock {
  margin-top: var(--sp-4);
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.done-clock__label { font-size: var(--fs-sub); color: var(--ink-2); }
.done-clock__value {
  font-family: var(--font-num);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--warn);
}

.done-deadline {
  margin: var(--sp-2) 0 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-sub);
  color: var(--ink-2);
}
.done-deadline svg { width: 15px; height: 15px; flex: none; }

/* 기한이 지난 뒤(관리자 확인 유예). 취소됐다고 단정하지 않는 문구가 들어간다 */
.done-grace {
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--warn);
  background: var(--warn-soft);
  border-radius: var(--r-card);
  text-align: left;
  font-size: var(--fs-sub);
  line-height: 1.55;
  color: var(--ink);
}
.done-grace b { display: block; margin-bottom: 4px; color: var(--warn); }

/* ── 예매 정보 카드 ── */
/*
 * 패딩 0 은 반드시 지켜져야 한다 — 포스터와 절취선이 카드 끝까지 닿아야 티켓처럼 보인다.
 * 아래쪽 @media(min-width:768px) 의 `.card { padding: var(--sp-5) }` 가 같은 특이도로
 * 뒤에 와서 이 값을 덮어썼고, 그 결과 넓은 화면에서 절취선이 카드 안쪽 41px 지점에
 * 떠 반원이 아니라 동그란 고리로 보였다. 클래스를 하나 더 붙여 특이도로 이긴다.
 */
.card.done-card { padding: 0; overflow: hidden; }

/* ---------------------------------------------------------------------------
 * 확정된 예매 = 입장권
 *
 * 대기 중에는 평범한 카드고, **결제가 확인된 뒤에만** 티켓 모양이 된다 —
 * 머리띠 · 절취선 · 좌석 바우처. 색과 표면은 나머지 화면 그대로 쓰고
 * 형태만 바꿔 "이건 들고 가는 것" 이라는 느낌을 준다.
 * ------------------------------------------------------------------------- */
/* 절취선 양옆의 반원을 카드 밖으로 내보내야 해서 클리핑을 푼다.
   포스터는 카드 가운데라 모서리에 걸리지 않는다. */
/* 확정 화면의 순서: 상태 머리말 → 입장권 → 결제 요약 → 취소 안내.
   대기 중에는 결제 안내가 먼저라 DOM 순서가 다르다. 그래서 여기서만 다시 잡는다. */
.rv--ticket [data-rv="head"] { order: 0; }
.rv--ticket [data-rv="infoSection"] { order: 1; }
.rv--ticket [data-rv="paidcard"] { order: 2; }
.rv--ticket [data-rv="cancelBox"] { order: 3; }

/*
 * 절취선의 반원은 카드가 잘라 낸다(overflow:hidden). 예전에는 overflow:visible 로
 * 원을 통째로 카드 밖에 띄웠는데, 테두리가 원 전체에 둘리면서 잘린 자국이 아니라
 * 카드 위에 얹힌 고리처럼 보였다. 넓은 화면일수록 그게 도드라졌다.
 */

.ticket__strip {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  border-radius: var(--r-card) var(--r-card) 0 0;
}
.ticket__strip-name {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ticket__strip-name svg { width: 17px; height: 17px; flex: none; color: var(--ok); }
.ticket__strip-state {
  margin-left: auto;
  flex: none;
  padding: 2px 10px;
  border-radius: var(--r-chip);
  background: var(--ok-soft);
  color: var(--ok);
  font-size: var(--fs-caption);
  font-weight: 700;
}

/* 절취선. 가운데는 점선, 양 끝은 카드를 파낸 듯한 반원 */
.ticket__perf {
  position: relative;
  height: 1px;
  margin: var(--sp-4) var(--sp-4) 0;
  border-top: 1px dashed var(--line-2);
}
.ticket__perf::before,
.ticket__perf::after {
  content: '';
  position: absolute;
  top: -10px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  /* 페이지 바탕색으로 덮어 카드가 잘려 나간 것처럼 보이게 한다.
     원의 중심을 카드 모서리에 정확히 두면, 카드의 overflow:hidden 이
     바깥 절반을 잘라 내고 안쪽 반원만 남는다 — 펀칭한 자국이 된다. */
  background: var(--bg);
  border: 1px solid var(--line);
}
.ticket__perf::before { left: calc(-1 * var(--sp-4) - 10px); }
.ticket__perf::after { right: calc(-1 * var(--sp-4) - 10px); }

.ticket__seat {
  margin: var(--sp-4);
  padding: var(--sp-4);
  border-radius: 14px;
  background: var(--surface-2);
  border: 1px solid var(--line);
}
.ticket__seat-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: 6px;
}
.ticket__seat-label {
  font-size: var(--fs-caption);
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
.ticket__seat-grade {
  margin-left: auto;
  padding: 2px 10px;
  border-radius: var(--r-chip);
  background: var(--surface-3);
  color: var(--ink-2);
  font-size: var(--fs-caption);
  font-weight: 600;
}
.ticket__seat-value {
  font-size: var(--fs-amount);
  font-weight: var(--fw-amount);
  letter-spacing: var(--ls-amount);
  margin-bottom: var(--sp-3);
}
.ticket__seat-who {
  display: flex;
  gap: var(--sp-5);
  flex-wrap: wrap;
  font-weight: 600;
}
.ticket__seat-k {
  display: block;
  font-size: var(--fs-caption);
  font-weight: 400;
  color: var(--ink-3);
  margin-bottom: 2px;
}


/*
 * 예매번호는 카드 안에서 **한 단계 눌린 면**에 얹는다.
 * 접수 완료 화면에서 가장 먼저 읽고 받아 적는 값이라, 주변(--surface)보다 어두운
 * 바탕(--bg)으로 한 덩어리처럼 보이게 한다. 복사 버튼은 --surface-2 라 그 위에서
 * 자연히 떠 보인다.
 */
.done-code {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
  margin: var(--sp-4);
  background: var(--bg);
  border: 1px solid var(--line);
}
.done-code__box { flex: 1 1 auto; min-width: 0; }
.done-code__label { font-size: var(--fs-caption); color: var(--ink-3); margin-bottom: 2px; }
.done-code__value {
  font-family: var(--font-num);
  font-size: var(--fs-section);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.done-poster {
  position: relative;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: flex-end;
  /* 사진이 없으면 --ev-photo 가 비고 아래 밤하늘만 남는다 (행사 카드와 같은 규칙) */
  background:
    var(--ev-photo, none) center / cover no-repeat,
    linear-gradient(180deg, #101722 0%, #1b1a1e 78%, #171417 100%);
}
.done-poster::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 35%, rgba(10, 12, 16, 0.82) 100%);
}
.done-poster__meta {
  position: relative;
  z-index: 1;
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.done-poster__name {
  font-size: var(--fs-section);
  font-weight: 700;
  color: #fff;
  /* 긴 행사명이 사진을 밀어내지 않게 한 줄로 자른다 */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.done-kv { padding: var(--sp-2) var(--sp-4) var(--sp-3); }

/* ── 결제 안내 카드 ── */
.paycard { padding: var(--sp-4); }

.paycard__amount {
  background: var(--surface-2);
  border-radius: 12px;
  padding: var(--sp-3) var(--sp-4);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.paycard__amount-label { font-size: var(--fs-sub); color: var(--ink-2); }
.paycard__won {
  font-size: var(--fs-amount);
  font-weight: var(--fw-amount);
  letter-spacing: var(--ls-amount);
}

.paycard__acct {
  background: var(--surface-2);
  border-radius: 12px;
  padding: var(--sp-2) var(--sp-4);
  margin-bottom: var(--sp-3);
}
.paycard__line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--line);
}
.paycard__line:last-child { border-bottom: 0; }
.paycard__line--full { justify-content: flex-start; word-break: break-all; }
.paycard__k { font-size: var(--fs-sub); color: var(--ink-3); flex: none; }
.paycard__v { font-weight: 700; text-align: right; word-break: break-all; }

.paycard__note {
  margin: var(--sp-3) 0 0;
  padding: var(--sp-3);
  border-radius: 10px;
  background: var(--surface-2);
  font-size: var(--fs-caption);
  line-height: 1.6;
  color: var(--ink-2);
}

.paybox {
  border: 2px solid var(--brand);
  border-radius: var(--r-card);
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--sh-pop);
}

.paybox__head {
  background: var(--brand);
  color: #fff;
  padding: var(--sp-3) var(--sp-4);
  font-weight: 800;
  font-size: var(--fs-body);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.paybox__body { padding: var(--sp-4); }

.payline { margin-bottom: var(--sp-4); }
.payline:last-child { margin-bottom: 0; }

.payline__label {
  font-size: var(--fs-caption);
  color: var(--ink-3);
  font-weight: 700;
  margin-bottom: 5px;
}

.payline__value {
  font-size: var(--fs-amount);
  font-weight: 800;
  line-height: 1.4;
  letter-spacing: -0.01em;
  font-family: var(--font-num);
  /* 계좌번호가 숫자 한가운데서 잘리지 않게 — 띄어쓰기에서 먼저 접는다 */
  word-break: normal;
  overflow-wrap: anywhere;
}

/* 계좌 문구는 한 줄이 길어 조금 작게 잡는다 */
.payline__value.account { font-size: 1.05rem; }

.payline__value.amount { color: var(--brand-soft); }

.payline__row {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
}
.payline__row .payline__value { flex: 1; }

.deadline {
  margin-top: 4px;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-card);
  background: var(--danger-soft);
  border: 1px solid var(--danger);
  color: var(--danger-text);
}
.deadline__label { font-size: var(--fs-caption); font-weight: 700; margin-bottom: 4px; opacity: 0.9; }
.deadline__value {
  font-size: 1.4rem;
  font-weight: 800;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
}
.deadline__remain { font-size: var(--fs-sub); font-weight: 700; margin-top: 2px; }

.copy-btn { flex: none; }
.copy-btn.is-done { border-color: var(--ok); background: var(--ok-soft); color: var(--ok); }

.code-badge {
  display: inline-block;
  padding: 10px 16px;
  border-radius: var(--r-btn);
  background: var(--surface-2);
  border: 1px dashed var(--line-2);
  font-family: var(--font-num);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: 0.06em;
}

/* ── 상태 배지 ────────────────────────────────────────────────────────────── */

.status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 12px;
  border-radius: var(--r-chip);
  font-size: var(--fs-caption);
  font-weight: 600;
}

.status::before {
  content: '';
  width: 8px; height: 8px;
  border-radius: 50%;
  background: currentColor;
}

.status--pending { background: var(--warn-soft); color: var(--warn); }
.status--confirmed { background: var(--ok-soft); color: var(--ok); }
.status--expired { background: var(--dim-soft); color: var(--dim); }
.status--cancelled { background: var(--danger-soft); color: var(--danger-text); }

.status-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-bottom: var(--sp-3);
}

/* ── 진행 표시 ────────────────────────────────────────────────────────────── */

.loading {
  display: flex;
  gap: var(--sp-2);
  align-items: center;
  color: var(--ink-3);
  font-size: var(--fs-sub);
  padding: var(--sp-6) 0;
  justify-content: center;
}

.loading::before {
  content: '';
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid var(--line-2);
  border-top-color: var(--brand-soft);
  animation: spin 0.7s linear infinite;
}

/* ── 데스크톱 (≥768px) ────────────────────────────────────────────────────── */

@media (min-width: 768px) {
  .wrap { padding: var(--sp-6) var(--sp-6) 110px; }
  .hero { padding: var(--sp-6) var(--sp-5); }
  .hero h1 { font-size: var(--fs-title-lg); }
  .card { padding: var(--sp-5); }
  .price-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .meta-row { grid-template-columns: 84px 1fr; }
  .cd-unit { min-width: 72px; }
  .cd-unit b { font-size: 2.2rem; }

  /* 관람객 화면은 가운데 480px 고정 컬럼(DESIGN 5절). 배치도만 예외로 넓힌다 */
  .flow-main { max-width: 480px; padding: var(--sp-5) var(--gutter) 110px; }
  .flow-main:has(.map-panel) { max-width: 720px; }

  /* 확대 뷰는 컨테이너 폭에 맞춘다 (전체 배치도의 min-width 는 위에서 걸린다) */
  .map-scroll .seatmap--zoom { min-width: 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation-duration: 0.01ms !important; }
}
