/* blue-hour — 한 장짜리 웹 포스터. 값은 전부 tokens.css 의 var() 다(raw 색 0).
 * v2: 예매 페이지(book/)의 규칙은 파일 끝 "예매 페이지" 절에 모았다 — 포스터 규칙을 그대로 딛고 더하기만 한다.
 * 배치: 1열(< 60rem) 이 기본, 12열(≥ 60rem) 을 위에 얹는다. 60rem 은 --breakpoint-wide 의 값 — 미디어 쿼리엔 var() 가 안 들어간다.
 * 설명은 _design/DESIGN.md · 구현 메모는 _design/NOTES.md. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
h1,
h2,
h3,
p,
ul,
dl,
dd {
  margin: 0;
}

button {
  font: inherit;
}

ul {
  padding: 0;
  list-style: none;
}

/* ── 벽 ──────────────────────────────────────────────────────────────────
 * 시트 바깥 여백. 노치·홈 바가 벽을 먹어도 시트는 안전 영역 안에 남는다. */
html {
  background: var(--color-bg-wall);
  color-scheme: dark;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  padding:
    max(var(--spacing-wall), env(safe-area-inset-top))
    max(var(--spacing-wall), env(safe-area-inset-right))
    max(var(--spacing-wall), env(safe-area-inset-bottom))
    max(var(--spacing-wall), env(safe-area-inset-left));
  background: var(--color-bg-wall);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-weight: var(--font-weight-body);
  line-height: var(--leading-body);
  word-break: keep-all;
  -webkit-font-smoothing: antialiased;
}

::selection {
  background: var(--color-ink);
  color: var(--color-bg);
}

/* ── 시트 ─────────────────────────────────────────────────────────────────
 * 높이는 벽을 뺀 한 화면(body 의 flex 가 채운다). 넘치면 늘어나고 페이지가 스크롤된다 — overflow 로 자르지 않는다. */
.sheet {
  position: relative;
  isolation: isolate;
  display: flex;
  flex: 1 0 auto;
  flex-direction: column;
  gap: var(--spacing-3);
  padding: var(--spacing-sheet);
  background: var(--color-bg);
}

/* 종이 결 — 정적. 글자 위에도 덮는다: 녹아웃 글자는 인쇄되지 않은 종이라서 같은 결이 보여야 한다. */
.sheet::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: url("/blue-hour/assets/grain.svg?v=8f05c882");
  opacity: 0.18;
  mix-blend-mode: soft-light;
  pointer-events: none;
}

/* ── 재단 표시 — 시트 모서리의 연장선, 벽 위에. ≥ 60rem 만 ─────────────────
 * 한 변은 --spacing-mark 이되 벽이 얇으면(60rem 근처 13px) 벽 안에 들어가게 줄인다 — 오른쪽으로 넘치면 가로 스크롤이 생긴다. */
.marks {
  display: none;
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.marks span {
  position: absolute;
  width: 0;
  height: 0;
}

.marks span::before,
.marks span::after {
  content: "";
  position: absolute;
  background: var(--color-haze);
}

.marks span::before {
  width: min(var(--spacing-mark), calc(var(--spacing-wall) - var(--spacing-2)));
  height: 1px;
}

.marks span::after {
  width: 1px;
  height: min(var(--spacing-mark), calc(var(--spacing-wall) - var(--spacing-2)));
}

.marks span:nth-child(1) { top: 0; left: 0; }
.marks span:nth-child(1)::before { top: 0; right: var(--spacing-1); }
.marks span:nth-child(1)::after { left: 0; bottom: var(--spacing-1); }

.marks span:nth-child(2) { top: 0; right: 0; }
.marks span:nth-child(2)::before { top: 0; left: var(--spacing-1); }
.marks span:nth-child(2)::after { right: 0; bottom: var(--spacing-1); }

.marks span:nth-child(3) { bottom: 0; left: 0; }
.marks span:nth-child(3)::before { bottom: 0; right: var(--spacing-1); }
.marks span:nth-child(3)::after { left: 0; top: var(--spacing-1); }

.marks span:nth-child(4) { bottom: 0; right: 0; }
.marks span:nth-child(4)::before { bottom: 0; left: var(--spacing-1); }
.marks span:nth-child(4)::after { right: 0; top: var(--spacing-1); }

/* ── 머리줄 ─────────────────────────────────────────────────────────────── */
.masthead {
  display: flex;
  justify-content: space-between;
  gap: var(--spacing-4);
  padding-bottom: var(--spacing-3);
  border-bottom: 1px solid var(--color-haze);
  color: var(--color-haze);
  font-family: var(--font-display);
  font-size: var(--text-micro);
  font-stretch: var(--font-stretch-wide);
  font-weight: 600;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
}

.masthead__kind,
.masthead__presents {
  display: none;
}

/* 320 폭에서는 125% 로 "SEONGSU UNDERGROUND HALL" 도 한 줄에 못 들어간다 — 머리줄이 두 줄로 접히느니 폭을 푼다 */
@media (max-width: 23.99rem) {
  .masthead {
    font-stretch: normal;
  }
}

/* ── 제목 — 화면에서 가장 큰 것, 움직이는 유일한 것 ─────────────────────────
 * 크기는 wdth 82%(가장 넓을 때)에서 칸에 맞게 잡혀 있다(DESIGN.md 6절) — 숨쉬기 중 어느 순간에도 옆 칸을 밀지 않는다.
 * 폭 변화는 매 프레임 레이아웃이다: 블록 상자라 바깥 크기는 그대로고, contain: layout 이 재배치를 이 상자 안에 가둔다. */
.title {
  font-weight: var(--font-weight-strong);
}

.title__type {
  display: block;
  contain: layout;
  font-family: var(--font-display);
  font-size: var(--text-title);
  font-stretch: var(--font-stretch-rest);
  font-weight: var(--font-weight-title);
  line-height: var(--leading-title);
  letter-spacing: var(--tracking-title);
  text-transform: uppercase;
}

.title__type > span {
  display: block;
}

/* 움직임을 원하는 사람에게만 켠다 — 기본값(reduced-motion 포함)은 72% 에 서 있는 제목이다.
 * -4.5s = 첫 편도의 한가운데(≈73%)에서 시작 — 정지한 제목과 첫인상이 같다. */
@media (prefers-reduced-motion: no-preference) {
  .title__type {
    animation: var(--animate-breathe);
    animation-delay: -4.5s;
  }
}

.title__sub {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--spacing-3);
  margin-top: var(--spacing-3);
  font-size: var(--text-quartet);
  line-height: var(--leading-tight);
}

.title__quartet {
  font-family: var(--font-display);
  font-stretch: var(--font-stretch-wide);
  letter-spacing: var(--tracking-quartet);
  text-transform: uppercase;
}

.title__dot {
  color: var(--color-haze);
}

/* ── 출연 ───────────────────────────────────────────────────────────────
 * 위의 2px 선이 호박색 세 곳 중 하나다. */
.lineup {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--spacing-3) var(--spacing-6);
  /* 1열에서 남는 높이는 제목과 출연 사이로 간다 — 12열과 같은 문법: 제목은 위, 출연·정보는 바닥 */
  margin-top: auto;
  padding-top: var(--spacing-3);
  border-top: 2px solid var(--color-accent);
}

.lineup li {
  display: flex;
  flex-direction: column;
}

/* v2 — 라틴 이름이 크고 한글 표기가 작다(외국 이름 쿼텟). 줄 수·높이는 v1 과 같다 */
.lineup__en {
  font-size: var(--text-name);
  font-weight: var(--font-weight-strong);
  line-height: var(--leading-tight);
}

.lineup__ko {
  margin-top: var(--spacing-1);
  color: var(--color-haze);
  line-height: var(--leading-tight);
}

.lineup__inst {
  color: var(--color-haze);
  font-family: var(--font-display);
  font-size: var(--text-micro);
  font-weight: 600;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
}

/* ── 정보 — 일시 → 장소 → 입장료 → 예매 ─────────────────────────────────
 * 숫자 크기는 칸 폭(cqi)도 따른다 — 60rem 근처에서 정보 칸이 좁아져도 "10.18 SUN" 이 칸을 넘지 않는다. */
.info {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  padding-top: var(--spacing-3);
  border-top: 1px solid var(--color-haze);
}

.info > p + p {
  padding-top: var(--spacing-3);
  border-top: 1px solid var(--color-haze);
}

.info__when {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--spacing-3);
}

.info__date {
  flex-basis: 100%;
  color: var(--color-accent);
  font-family: var(--font-display);
  font-size: min(var(--text-date), 15cqi);
  font-stretch: var(--font-stretch-date);
  font-weight: var(--font-weight-date);
  line-height: var(--leading-tight);
  font-variant-numeric: tabular-nums;
}

.info__date-ko {
  margin-top: var(--spacing-2);
  font-weight: var(--font-weight-strong);
}

.info__doors {
  color: var(--color-haze);
}

.info__venue {
  display: block;
  font-size: var(--text-venue);
  font-weight: var(--font-weight-strong);
  line-height: var(--leading-tight);
}

.info__venue-en {
  display: block;
  margin-top: var(--spacing-1);
  color: var(--color-haze);
}

.info__price {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--spacing-3);
}

.info__seats {
  color: var(--color-haze);
}

/* 예매 — 호박 면. 움직임 없이 색만 바뀐다(120ms). */
.book {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-4);
  min-height: var(--spacing-12);
  padding: 0 var(--spacing-4);
  border-radius: var(--radius-none);
  background: var(--color-accent);
  box-shadow: var(--shadow-none);
  color: var(--color-on-accent);
  font-weight: var(--font-weight-strong);
  text-decoration: none;
  transition:
    background-color 120ms var(--ease-out),
    color 120ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
}

.book:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

@media (hover: hover) and (pointer: fine) {
  .book:hover {
    background: var(--color-ink);
  }
}

.book:active {
  background: var(--color-bg-wall);
  color: var(--color-accent);
}

/* ── 12열 — ≥ 60rem ────────────────────────────────────────────────────
 * 열은 minmax(0, 1fr) 고정 — 내용 크기로 열이 움직이면 제목 숨쉬기가 정보 칸을 흔든다.
 * 제목은 위(머리줄 바로 아래)에, 출연 줄과 예매 버튼은 같은 바닥선에 붙는다. */
@media (min-width: 60rem) {
  .sheet {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto 1fr auto;
    gap: 0 var(--spacing-6);
  }

  .marks {
    display: block;
  }

  .masthead {
    grid-column: 1 / -1;
  }

  .masthead__kind {
    display: block;
  }

  .masthead__presents {
    display: inline;
  }

  .title {
    grid-column: 1 / 9;
    grid-row: 2;
    align-self: start;
    padding-top: var(--spacing-6);
  }

  .title__type {
    font-size: var(--text-title-wide);
  }

  .title__sub {
    margin-top: var(--spacing-4);
  }

  .lineup {
    grid-column: 1 / 9;
    grid-row: 3;
    align-self: end;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-top: var(--spacing-6);
    padding-top: var(--spacing-4);
  }

  .info {
    grid-column: 9 / -1;
    grid-row: 2 / 4;
    gap: var(--spacing-4);
    padding: var(--spacing-6) 0 0 var(--spacing-6);
    border-top: 0;
    border-left: 1px solid var(--color-haze);
  }

  .info > p + p {
    padding-top: var(--spacing-4);
  }

  .info__when {
    display: block;
  }

  .info__date-ko,
  .info__doors {
    display: block;
  }

  .info__date {
    font-size: min(var(--text-date), 23cqi);
    line-height: var(--leading-title);
  }

  .info__hour {
    display: block;
  }

  .info__date-ko {
    margin-top: var(--spacing-3);
  }

  .info__price {
    display: block;
  }

  .info__price > span {
    display: block;
  }

  .lineup__inst {
    margin-top: var(--spacing-1);
  }

  /* 예매는 바닥에 — 출연 줄과 같은 바닥선 */
  .book {
    margin-top: auto;
  }
}

/* ══ 예매 페이지 /blue-hour/book/ (v2) ════════════════════════════════════
 * 포스터의 문법(벽·시트·머리줄·재단 표시·종이 결·12열)을 그대로 딛고, 정보 칼럼 자리에 1도 인쇄 주문서가 들어온다.
 * Operate 화면 — 누르는 것은 전부 48px 이상, 결제 56px. 움직이는 것은 완료 티켓 찍기(M2) 하나.
 * 호박은 셋뿐: 미터의 선택 눈금 · 합계 숫자 · 결제 면. 완료 뒤에는 티켓 면 하나. */

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

.wide-only {
  display: none;
}

/* ── 머리줄 — 왼쪽 토막이 뒤로 가는 링크(48px)가 된다 ─────────────────── */
.masthead--book {
  align-items: center;
  padding-bottom: 0;
}

.back {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
  min-height: var(--spacing-target);
  padding-right: var(--spacing-3);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-stretch: normal;
  font-weight: var(--font-weight-strong);
  letter-spacing: normal;
  text-decoration: none;
  text-transform: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.back__label {
  text-decoration: underline 1px;
  text-underline-offset: 4px;
}

@media (hover: hover) and (pointer: fine) {
  .back:hover .back__label {
    text-decoration-thickness: 2px;
  }
}

.back:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* ── 공연 요약 머리 — 제목은 숨 쉬지 않는다(쉼 폭 72% 에 멈춘 채) ─────────── */
.book-head {
  display: flex;
  flex-direction: column;
}

/* h1 자신도 제목 크기를 갖는다 — 자식이 크기를 모두 따로 들고 있어 보이는 것은 같고, 문서 위계(h1 > h2 > h3)가 글자 크기로도 맞는다 */
.title--book,
.title--book .title__type {
  font-size: var(--text-title-book);
}

.title--book .title__type {
  animation: none;
}

/* 1열은 BLUE HOUR 한 줄 */
.title--book .title__type > span {
  display: inline;
}

.summary {
  display: flex;
  flex-direction: column;
  margin-top: var(--spacing-3);
}

.summary__when time {
  font-weight: var(--font-weight-strong);
}

.summary__date,
.summary__doors,
.summary__venue-en {
  display: none;
}

.summary__where {
  color: var(--color-haze);
}

/* ── 책상 — 주문서와 티켓이 같은 칸에 겹친다 ───────────────────────────────
 * 1열에서 남는 높이는 요약과 주문서 사이 한 곳으로 간다(주문서를 엄지 쪽으로). */
.desk {
  display: grid;
  margin-top: auto;
}

.desk > .order,
.desk > .ticket {
  grid-area: 1 / 1;
}

/* 완료: 주문서는 자리만 지킨다(inert 는 main.js) — 칸 높이가 뛰지 않고, 티켓 뒤로 비치지 않는다 */
.desk.is-done > .order {
  visibility: hidden;
}

/* ── 주문서 — 1px 테두리 상자(인쇄된 주문 양식). 면이 없어 코발트가 비친다 ── */
.order {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--spacing-4);
  border: 1px solid var(--color-haze);
}

/* 1열에서는 상자 자체가 제목이다 — h2 는 읽기 도구에만 */
.order__title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.order__title-en {
  color: var(--color-haze);
  font-family: var(--font-display);
  font-size: var(--text-micro);
  font-stretch: var(--font-stretch-wide);
  font-weight: 600;
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
}

.step {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--spacing-2);
  padding: var(--spacing-row) 0;
  border-top: 1px solid var(--color-haze);
}

.order__title + .step {
  padding-top: 0;
  border-top: 0;
}

.step__head {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-2);
  font-size: var(--text-body);
  font-weight: var(--font-weight-strong);
  line-height: var(--leading-body);
  white-space: nowrap;
}

.step__no {
  color: var(--color-haze);
  font-family: var(--font-display);
  font-size: var(--text-micro);
  font-weight: var(--font-weight-strong);
  letter-spacing: var(--tracking-micro);
  font-variant-numeric: tabular-nums;
}

.step__hint {
  color: var(--color-haze);
}

/* 02·03 — 머리와 내용이 한 줄, 내용끼리는 같은 세로선에서 시작한다("02 좌석"·"03 금액" 은 폭이 같다) */
.step--seats,
.step--amount {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: center;
  align-items: baseline;
  column-gap: var(--spacing-4);
}

.seats,
.seats__legend,
.total {
  grid-column: 1 / -1;
}

/* ── 01 인원 — 머리·안내는 왼쪽, 스테퍼는 오른쪽 ─────────────────────── */
.step--count {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-4);
}

.stepper {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--spacing-2);
}

.stepper__btn {
  display: grid;
  place-items: center;
  width: var(--spacing-target);
  height: var(--spacing-target);
  padding: 0;
  border: 2px solid var(--color-ink);
  border-radius: var(--radius-none);
  background: none;
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: 1.5rem; /* 24px — 48px 칸의 절반. 글자 기호라 --text-* 사다리 밖 */
  font-weight: var(--font-weight-strong);
  line-height: 1;
  cursor: pointer;
  transition:
    background-color 120ms var(--ease-out),
    color 120ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
}

@media (hover: hover) and (pointer: fine) {
  .stepper__btn:not([aria-disabled="true"]):hover {
    background: var(--color-ink);
    color: var(--color-on-accent);
  }
}

.stepper__btn:not([aria-disabled="true"]):active {
  background: var(--color-bg-wall);
  color: var(--color-ink);
}

/* 끝 값 — 실선 2px ↔ 점선 1px, 종이 ↔ 옅은 하늘. 모양이 확실히 다르다 */
.stepper__btn[aria-disabled="true"] {
  border: 1px dashed var(--color-haze);
  color: var(--color-haze);
  cursor: not-allowed;
}

.stepper__btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

.stepper__value {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-1);
  padding-inline: var(--spacing-1);
}

.count {
  min-width: 1ch;
  font-family: var(--font-display);
  font-size: var(--text-count);
  font-stretch: var(--font-stretch-date);
  font-weight: var(--font-weight-date);
  line-height: 1;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ── 02 좌석 — 1 눈금 = 1석. 팔림 82 · 선택 n(호박) · 남음(바닥의 짧은 토막) ──
 * 1열 60 × 2줄, 12열 120 × 1줄. 선택 눈금은 data-pick(main.js) 과 nth-child 로 칠한다 — 스크립트가 없어도 1석이 칠해져 있다. */
.seats {
  display: grid;
  grid-template-columns: repeat(60, minmax(0, 1fr));
  grid-template-rows: repeat(2, var(--spacing-3));
  gap: var(--spacing-1) 1px;
  margin-top: var(--spacing-1);
}

.seats i {
  align-self: end;
  height: var(--spacing-1);
  background: var(--color-haze);
}

.seats i:nth-child(-n + 82) {
  height: 100%;
}

.seats i:nth-child(83),
.seats[data-pick="2"] i:nth-child(84),
.seats[data-pick="3"] i:nth-child(n + 84):nth-child(-n + 85),
.seats[data-pick="4"] i:nth-child(n + 84):nth-child(-n + 86) {
  height: 100%;
  background: var(--color-accent);
}

.seats__legend {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--spacing-4);
  color: var(--color-haze);
  font-variant-numeric: tabular-nums;
}

.seats__key {
  display: inline-flex;
  align-items: baseline;
  gap: var(--spacing-2);
}

/* 견본 — 글자 기호가 아니라 미터 눈금과 같은 모양 */
.key {
  display: inline-block;
  width: var(--spacing-1);
  height: var(--spacing-3);
  background: var(--color-haze);
}

.key--pick {
  background: var(--color-accent);
}

.key--left {
  height: var(--spacing-1);
}

/* ── 03 금액 — 1열은 한 줄로 합친다 ──────────────────────────────────── */
.amount {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--spacing-2);
  font-variant-numeric: tabular-nums;
}

.amount__row {
  display: flex;
  gap: 0.3em;
}

.amount__label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.amount__row--door {
  color: var(--color-haze);
}

.amount__row--door::before {
  content: "·";
  margin-right: var(--spacing-1);
}

/* 합계 — 이 페이지 유일의 live 영역. 숫자는 호박 44px 이상(작은 호박 글자 금지) */
.total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--spacing-4);
  margin-top: var(--spacing-1);
}

.total__label {
  font-weight: var(--font-weight-strong);
}

.total__sum {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-1);
}

.total__num {
  color: var(--color-accent);
  font-family: var(--font-display);
  font-size: var(--text-total);
  font-stretch: var(--font-stretch-date);
  font-weight: var(--font-weight-date);
  line-height: var(--leading-title);
  font-variant-numeric: tabular-nums;
}

/* ── 결제 — 절취선 아래. 포스터 예매 면과 같은 규칙, 56px ─────────────── */
.pay-block {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  padding-top: var(--spacing-4);
  border-top: 1px dashed var(--color-haze);
}

.pay {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-4);
  width: 100%;
  min-height: var(--spacing-target-lg);
  padding: 0 var(--spacing-4);
  border: 0;
  border-radius: var(--radius-none);
  background: var(--color-accent);
  box-shadow: var(--shadow-none);
  color: var(--color-on-accent);
  font-size: var(--text-name);
  font-weight: var(--font-weight-strong);
  text-align: left;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition:
    background-color 120ms var(--ease-out),
    color 120ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
}

.pay:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

@media (hover: hover) and (pointer: fine) {
  .pay:hover {
    background: var(--color-ink);
  }
}

.pay:active {
  background: var(--color-bg-wall);
  color: var(--color-accent);
}

.pay__note {
  color: var(--color-haze);
  text-wrap: balance;
}

/* ── 완료 티켓 — 두 번째 판(호박) 한 장. 위 글자·선은 전부 밤색 하나(종이·옅은 하늘 금지 1.53 · 1.28:1) ──
 * 주문서와 같은 칸·같은 크기. 종이 결(시트 ::after)이 위에 그대로 덮인다. */
.ticket {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--spacing-4);
  min-width: 0;
  padding: var(--spacing-4);
  background: var(--color-bg-ticket);
  color: var(--color-on-accent);
}

.ticket[hidden] {
  display: none;
}

/* M2 — 결제 버튼이 있던 아래 변에서 위로 찍혀 올라온다. 한 번만, 앞으로만 */
@media (prefers-reduced-motion: no-preference) {
  .ticket.is-printing {
    animation: var(--animate-ticket);
  }
}

.ticket__top {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
}

.ticket__title {
  align-self: flex-start;
  font-size: var(--text-venue);
  font-weight: var(--font-weight-strong);
  line-height: var(--leading-tight);
}

.ticket__title:focus {
  outline: none;
}

.ticket__title:focus-visible {
  outline: 2px solid var(--color-on-accent);
  outline-offset: 3px;
}

.ticket__no {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}

.ticket__label {
  font-weight: var(--font-weight-strong);
  line-height: var(--leading-tight);
}

.ticket__code {
  font-family: var(--font-display);
  font-size: var(--text-count);
  font-stretch: var(--font-stretch-date);
  font-weight: var(--font-weight-date);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.ticket__body {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-4);
}

/* QR 자리 — 정사각 테두리 안 2×2: 세 모서리 찾기 무늬(바깥 2px 사각 + 안 채운 사각) + 네 번째 모서리 ADMIT n */
.qr {
  display: grid;
  flex: none;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  width: 6rem;
  aspect-ratio: 1;
  padding: var(--spacing-2);
  border: 2px solid var(--color-on-accent);
}

.qr i {
  position: relative;
  width: 72%;
  aspect-ratio: 1;
  border: 2px solid var(--color-on-accent);
}

.qr i::after {
  content: "";
  position: absolute;
  inset: 22%;
  background: var(--color-on-accent);
}

.qr i:nth-child(2) { justify-self: end; }
.qr i:nth-child(3) { align-self: end; }

.qr__admit {
  display: flex;
  place-self: end;
  flex-direction: column;
  align-items: flex-end;
  font-family: var(--font-display);
  font-size: var(--text-micro);
  font-weight: var(--font-weight-strong);
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.qr__n {
  font-size: var(--text-venue);
  font-weight: var(--font-weight-date);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.ticket__meta {
  display: flex;
  flex-direction: column;
  line-height: var(--leading-body);
  font-variant-numeric: tabular-nums;
}

.ticket__when {
  font-family: var(--font-display);
  font-size: var(--text-name);
  font-stretch: var(--font-stretch-date);
  font-weight: var(--font-weight-date);
  line-height: var(--leading-tight);
  padding-bottom: var(--spacing-1);
}

/* 절취선(밤색 점선) 아래 — 안내 · 행동 둘 */
.ticket__foot {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  padding-top: var(--spacing-4);
  border-top: 1px dashed var(--color-on-accent);
}

.ticket__note {
  font-weight: var(--font-weight-strong);
  text-wrap: balance;
}

.ticket__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--spacing-3);
}

.ticket__back,
.ticket__again {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-2);
  min-height: var(--spacing-target);
  padding: 0 var(--spacing-3);
  border: 2px solid var(--color-on-accent);
  border-radius: var(--radius-none);
  font-weight: var(--font-weight-strong);
  text-decoration: none;
  transition:
    background-color 120ms var(--ease-out),
    color 120ms var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
}

/* ← 포스터로 = 밤 면 + 호박 글자(9.65:1) */
.ticket__back {
  background: var(--color-on-accent);
  color: var(--color-accent);
}

/* 다시 고르기 = 밤색 테두리만 */
.ticket__again {
  background: none;
  color: var(--color-on-accent);
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .ticket__back:hover {
    text-decoration: underline 2px;
    text-underline-offset: 4px;
  }

  .ticket__again:hover {
    background: var(--color-on-accent);
    color: var(--color-accent);
  }
}

.ticket__again:active {
  background: var(--color-on-accent);
  color: var(--color-accent);
}

/* 호박 면 위에서 호박 윤곽은 사라진다 → 티켓 안은 밤색 윤곽 */
.ticket__back:focus-visible,
.ticket__again:focus-visible {
  outline: 2px solid var(--color-on-accent);
  outline-offset: 3px;
}

/* ── 출연 — 한 사람 한 줄: 라틴 이름(크게) · 한글 표기(작게) · 악기(오른쪽 끝) ── */
.cast li {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr) auto;
  align-items: baseline;
  column-gap: var(--spacing-3);
  padding: var(--spacing-2) 0;
  border-top: 1px solid var(--color-haze);
}

.cast__en {
  font-size: var(--text-name);
  font-weight: var(--font-weight-strong);
  line-height: var(--leading-tight);
}

.cast__ko {
  color: var(--color-haze);
  line-height: var(--leading-tight);
}

.cast__inst {
  color: var(--color-haze);
  font-family: var(--font-display);
  font-size: var(--text-micro);
  font-weight: 600;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-micro);
  text-align: right;
  text-transform: uppercase;
}

/* ── 예매 12열 — ≥ 60rem ─────────────────────────────────────────────
 * 열 1–7 요약(위) · 출연(바닥), 열 8–12 주문서(머리줄 아래 ~ 시트 바닥 한 칸). 포스터와 같은 두 끝: 제목은 위, 출연·주문서 바닥은 같은 바닥선. */
@media (min-width: 60rem) {
  .wide-only {
    display: inline;
  }

  .book-head {
    grid-column: 1 / 8;
    grid-row: 2;
    align-self: start;
  }

  .title--book,
  .title--book .title__type {
    font-size: var(--text-title-book-wide);
  }

  .title--book .title__type > span {
    display: block;
  }

  .summary {
    margin-top: var(--spacing-6);
  }

  .summary__date {
    display: block;
    margin-bottom: var(--spacing-2);
    font-family: var(--font-display);
    font-size: var(--text-venue);
    font-stretch: var(--font-stretch-date);
    font-weight: var(--font-weight-date);
    line-height: var(--leading-tight);
    font-variant-numeric: tabular-nums;
  }

  .summary__doors {
    display: inline;
    color: var(--color-haze);
  }

  .summary__where {
    margin-top: var(--spacing-2);
  }

  .summary__venue {
    display: block;
    color: var(--color-ink);
    font-weight: var(--font-weight-strong);
  }

  .summary__venue-en {
    display: block;
  }

  .desk {
    grid-column: 8 / -1;
    grid-row: 2 / 4;
    margin-top: 0;
    padding-top: var(--spacing-6);
  }

  .order {
    padding: var(--spacing-6);
  }

  .order__title {
    position: static;
    display: flex;
    align-items: baseline;
    gap: var(--spacing-3);
    width: auto;
    height: auto;
    margin: 0;
    padding-bottom: var(--spacing-row);
    overflow: visible;
    clip-path: none;
    font-size: var(--text-body);
    line-height: var(--leading-body);
  }

  .order__title + .step {
    padding-top: var(--spacing-row);
    border-top: 1px solid var(--color-haze);
  }

  /* 남는 높이는 네 덩어리(01 · 02 · 03 · 결제) 사이에 고르게 — 한 곳에 고이지 않는다(qa-1 P3) */
  .step {
    flex: 1 0 auto;
  }

  .seats {
    grid-template-columns: repeat(120, minmax(0, 1fr));
    grid-template-rows: var(--spacing-8);
  }

  .amount {
    display: block;
  }

  .amount__label {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
  }

  .amount__row--door::before {
    content: none;
  }

  .ticket {
    padding: var(--spacing-6);
  }

  .ticket__top {
    gap: var(--spacing-4);
  }

  .ticket__body {
    gap: var(--spacing-6);
  }

  /* 160px — 단 60rem 근처(티켓 348px)에서는 요약 줄이 접히지 않게 칸 폭의 1/3 로 */
  .qr {
    width: min(10rem, 34cqi);
    padding: var(--spacing-3);
  }

  .cast {
    grid-column: 1 / 6;
    grid-row: 3;
    align-self: end;
    margin-top: var(--spacing-6);
  }
}

/* ── 예매 12열, 낮은 창(노트북 1366×657 · 1280×720 · 1536×730 · 1440×800) ──
 * 1440×900 은 위 규칙 그대로 한 장. 이보다 낮으면 왼쪽(제목·요약·출연 4줄)이 시트를 넘어 스크롤이 생겼다(1366×657 +109px, 실측).
 * 출연을 2×2 로 접고, 영문 장소 줄을 빼고, 여백을 한 단 줄인다 — 결제 버튼·안내 줄까지 첫 화면에 남는다. */
@media (min-width: 60rem) and (max-height: 51.99rem) {
  .title--book {
    padding-top: var(--spacing-4);
  }

  .summary {
    margin-top: var(--spacing-4);
  }

  .summary__venue-en {
    display: none;
  }

  .desk {
    padding-top: var(--spacing-4);
  }

  .order,
  .ticket {
    padding: var(--spacing-4);
  }

  .seats {
    grid-template-rows: var(--spacing-6);
  }

  .step {
    row-gap: var(--spacing-1);
  }

  .pay-block {
    padding-top: var(--spacing-3);
  }

  .cast {
    container: cast / inline-size;
    grid-column: 1 / 8;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--spacing-6);
    margin-top: var(--spacing-4);
  }

  /* 2×2 한 칸이 300px 아래(60rem 근처)면 한 줄에 셋이 안 든다 — 이름이 낱말 가운데서 꺾이느니 한글 표기를 아랫줄로 */
  @container cast (max-width: 39rem) {
    .cast li {
      grid-template-columns: minmax(0, 1fr) auto;
      row-gap: var(--spacing-1);
    }

    .cast__en {
      grid-area: 1 / 1;
    }

    .cast__inst {
      grid-area: 1 / 2;
    }

    .cast__ko {
      grid-area: 2 / 1 / 3 / -1;
    }
  }
}
