/* 폰트는 CDN이 아니라 번들한다. 부스는 오프라인으로 돌기 때문에
   외부에서 불러오면 현장에서 시스템 기본 폰트로 떨어진다. */
@font-face {
  font-family: 'Pretendard';
  src: url('assets/fonts/PretendardVariable.woff2') format('woff2-variations');
  font-weight: 45 920;
  font-display: swap;
}
@font-face {
  font-family: 'Figtree';
  src: url('assets/fonts/Figtree-latin.woff2') format('woff2-variations');
  font-weight: 300 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212, U+2215;
}

:root {
  --app-w: 1080px; /* 현장에서 실제 아이맥을 보고 이 값만 고치면 된다 */
  --cream: #F9FFD4;
  --ink: #1A1A1A;
  --orange: #FF6500;
  --gray: #888;
  --house-bg: #F9FFD4;
  /* Figtree 를 먼저 둔다. Figtree 에는 한글 글리프가 없어서 라틴 문자만
     Figtree 로 그려지고 한글은 자동으로 Pretendard 로 넘어간다. */
  --font: 'Figtree', 'Pretendard', -apple-system, 'Helvetica Neue', sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden; /* 부스 키오스크: 어떤 화면에서도 스크롤이 생기면 안 된다 */
  background: var(--cream);
}

body {
  font-family: var(--font);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  background: var(--cream);
  /* 한글은 기본이 글자 단위 줄바꿈이라 "들려주세 / 요" 처럼 단어 한가운데가
     잘린다. 어절 단위로 넘기게 한다. 안내문·에러문구·토스트 전부 해당된다. */
  word-break: keep-all;
  overflow-wrap: break-word;
}

/* 결과 화면은 화면 전체가 하우스 컬러다. 컬럼 안쪽만 칠하면
   좌우에 크림색 띠가 남는다.
   html 까지 칠하는 이유: iOS 에서 끝까지 스크롤해 튕길 때(러버밴드)
   body 바깥이 드러나는데, 거기가 크림색이면 색이 깜빡인다. */
html:has(body[data-state="result"]),
body[data-state="result"] {
  background: var(--house-bg);
}

button {
  font-family: inherit;
  cursor: pointer;
  border-radius: 0;
}

img { display: block; max-width: 100%; }

/* ---- 고정 폭 중앙 컬럼 ------------------------------------------------- */
/* 화면 전체를 채우지 않는다. 아이맥에서 열었을 때 화면 폭의 절반 정도만
   차지하는 고정 폭 컬럼을 가운데 둔다 (quiz-demo #qa 와 같은 구조). */
/* 아이맥에서는 --app-w 그대로 고정된다. 다만 창이 그보다 좁아지면 따라 줄어든다.
   min() 없이 고정 폭만 쓰면 창을 줄였을 때 컬럼이 뷰포트를 넘어가고,
   html 의 overflow:hidden 때문에 넘친 부분이 스크롤도 안 되고 그냥 잘린다. */
/* 배경은 body 가 칠한다. #app 이 따로 칠하면 결과 화면에서 컬럼 바깥은
   하우스 컬러인데 컬럼 안쪽 여백만 크림색으로 남아 띠가 생긴다. */
#app {
  width: min(var(--app-w), 100vw);
  height: 100vh;
  margin: 0 auto;
  padding: 0 clamp(0px, 2vw, 24px);
  overflow: hidden;
  background: transparent;
}

.screen {
  width: 100%;
  height: 100%;
  display: none;
  flex-direction: column;
  overflow: hidden;
}

body[data-state="idle"] #screen-idle,
body[data-state="select"] #screen-select,
body[data-state="ready"] #screen-ready,
body[data-state="shooting"] #screen-shooting,
body[data-state="result"] #screen-result,
body[data-state="error"] #screen-error {
  display: flex;
}

/* ---- 카메라 (ready / shooting 화면 사이를 이동하는 공용 요소) ---- */

.camera-video { display: none; }

/* 프리뷰 비율은 슬롯 비율(3:2)과 반드시 같아야 한다.
   16:9 로 넓게 보여주면 관람객은 화면 가장자리를 믿고 자리를 잡는데,
   실제로 저장되는 컷은 computeCrop 으로 좌우를 잘라낸 3:2 라서
   가장자리에 선 사람이 저장본에서 잘려나간다. 보이는 대로 찍혀야 한다. */
.camera-frame {
  position: relative;
  aspect-ratio: 3 / 2;
  width: auto;
  height: 55vh;
  max-height: 55vh;
  max-width: 100%;
  margin: 0 auto;
  background: #000;
  overflow: hidden;
  flex: 0 0 auto;
}

.camera-frame .camera-video {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
  z-index: 1;
}

/* ==== 1. 대기 ==== */

/* 버튼을 화면 맨 아래에 붙이지 않는다. 영상 바로 아래에 두고
   그 밑으로 여백을 크게 남겨 시선이 버튼에서 멈추게 한다. */
#screen-idle {
  cursor: pointer;
  align-items: center;
  justify-content: flex-start;
  gap: clamp(12px, 2vh, 28px);
  padding: clamp(12px, 3vh, 32px) 0 clamp(60px, 14vh, 150px);
}

.idle-video-wrap {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.idle-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* press to start! — 누르고 싶게. 숨쉬듯 커졌다 작아지고, 빛이 한 번씩 훑고 지나간다.
   부스에서 멀리서도 "저건 눌러야 하는 것"으로 읽혀야 한다. */
.touch-bar {
  position: relative;
  overflow: hidden;
  flex: 0 0 auto;
  border: none;
  background: var(--orange);
  color: var(--ink);
  text-align: center;
  padding: clamp(16px, 3vh, 30px) clamp(40px, 8vh, 90px);
  font-size: clamp(20px, 3.4vh, 32px);
  font-weight: 800;
  letter-spacing: 0.06em;
  animation: breathe 2.2s ease-in-out infinite;
  transition: none;
}

.touch-bar:hover { opacity: 1; }
.touch-bar:active { transform: scale(0.97); }

@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.05); }
}

/* 움직임을 불편해하는 사용자를 위해 (macOS 손쉬운 사용 > 동작 줄이기) */
@media (prefers-reduced-motion: reduce) {
  .touch-bar { animation: none; }
}

/* ==== 2. 프레임 선택 ==== */

#screen-select {
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 4vh, 40px);
  padding: clamp(16px, 3vh, 32px) 24px;
}

/* 본문 톤(quiz-demo .qt): weight 500 */
.select-title {
  font-size: clamp(19px, 3.4vh, 29px);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-align: center;
  word-break: keep-all;
}

.house-cards {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: stretch;
  gap: 14px;
}

/* 카드/선택지 톤(quiz-demo .opt): 옅은 흰 배경 + 얇은 테두리.
   단, 하우스 카드는 설계서 §4.2에 따라 각 하우스의 배경색 위에 올린다
   (JS가 인라인 background로 house.bg를 지정한다).
   width는 %가 아니라 flex:1 로 컬럼 폭(--app-w)에 자동으로 맞춘다. */
/* color 를 반드시 지정한다. <button> 은 iOS Safari 에서 색을 안 주면
   시스템 강조색(파랑)으로 그려진다. 데스크톱 Chrome 은 검정이라 안 보인다. */
.house-card {
  flex: 1 1 0;
  min-width: 0;
  color: var(--ink);
  -webkit-text-fill-color: currentColor;
  border: 1px solid rgba(0, 0, 0, 0.11);
  border-radius: 0;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 14px 10px 16px;
  transition: opacity 0.18s ease;
}

.house-card:hover:not(.disabled):not(.selecting) {
  opacity: 0.82;
}

/* 선택된 카드(quiz-demo .opt.sel): 배경 잉크, 글자 크림 */
.house-card.selecting {
  background: var(--ink) !important;
}
.house-card.selecting .house-card-label {
  color: var(--cream);
}

.house-card-imgwrap {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  margin-bottom: 10px;
}

.house-card-img,
.house-card-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.house-card-canvas {
  display: none;
}
.house-card-canvas.show {
  display: block;
}

/* 녹아웃 성공 시 원본 <img>를 감춘다. display:none 이 아니라 opacity:0 인 이유:
   원본은 레이아웃과 테스트의 '/houses/' 경로 탐색을 위해 남아 있어야 한다.
   이걸 빼먹으면 흰 배경 원본이 투명해진 캔버스 뒤로 그대로 비쳐서
   녹아웃이 아무 효과가 없다. */
.house-card-img.knocked {
  opacity: 0;
}

.house-card-label {
  font-size: clamp(14px, 2.2vh, 20px);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-align: center;
}

.house-card.disabled {
  opacity: 0.35;
  pointer-events: none;
}

/* ==== 3. 준비 ==== */

/* 3열 그리드: 뒤로 | 아이콘(가운데) | 빈칸.
   아이콘을 가운데 두면 좌우 폭이 어떻게 변하든 잘리지 않는다.
   (이전엔 하우스 이름을 우상단에 붙여둬서 창을 줄이면 텍스트가 잘렸다.) */
.ready-topbar {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: clamp(12px, 2.4vh, 24px) 4px;
}

.ready-topbar > #btn-back { justify-self: start; }
.ready-topbar-spacer { display: block; }

.ready-house-icon {
  justify-self: center;
  height: clamp(56px, 10vh, 104px);
  width: auto;
  max-width: none;
  object-fit: contain;
}

.ready-bottom {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ==== 4. 촬영 ==== */

.shooting-top {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: clamp(12px, 2.2vh, 22px) 0;
}

.shot-progress {
  font-size: clamp(14px, 2vh, 18px);
  font-weight: 600;
  letter-spacing: 0.06em;
}

.shot-dots {
  display: flex;
  gap: 8px;
}

/* 각진 톤에 맞춰 원이 아닌 사각 인디케이터 사용 */
.shot-dot {
  width: 12px;
  height: 12px;
  border-radius: 0;
  border: 2px solid var(--ink);
  background: transparent;
}

.shot-dot.filled {
  background: var(--orange);
  border-color: var(--orange);
}

.countdown {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: none;
  align-items: center;
  justify-content: center;
  font-size: clamp(60px, 20vh, 160px);
  font-weight: 700;
  color: #fff;
  letter-spacing: -0.03em;
  text-shadow: 0 6px 24px rgba(0,0,0,.6);
  pointer-events: none;
}

.countdown.show { display: flex; }

.flash {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: #fff;
  opacity: 0;
  pointer-events: none;
}

.flash.show {
  opacity: 1;
  transition: opacity 60ms ease-out;
}

.review-frame {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,.55);
}

.review-frame.show { display: flex; }

.review-frame img {
  max-width: 90%;
  max-height: 90%;
  border: 4px solid #fff;
  box-shadow: 0 12px 32px rgba(0,0,0,.5);
}

/* ==== 5. 결과 ==== */

#screen-result {
  background: var(--house-bg);
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 2.4vh, 28px) 24px;
}

.result-inner {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(20px, 4vh, 40px);
}

.result-photo-wrap {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 설계서 §3: 결과 이미지(4:5 세로)는 높이 기준 52vh — 버튼·QR과 함께
   스크롤 없이 한 화면에 들어와야 한다. */
/* 테두리·그림자 없음. 합성 이미지 자체가 하우스 배경색까지 포함한 완성본이라
   프레임을 덧대면 액자 안의 액자가 된다. */
.result-image {
  max-height: 52vh;
  width: auto;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

/* 360px: 안내 문구에서 가장 긴 줄("여러분의 피드백은 … 큰 힘이 됩니다.")이
   한 줄에 들어가는 폭. 이보다 좁으면 줄 끝이 지저분하게 흘러넘친다. */
.result-side {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 2.6vh, 28px);
  width: 360px;
  max-width: 40vw;
}

.result-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.result-survey {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  border-top: 2px solid rgba(26,26,26,.2);
  padding-top: clamp(12px, 2vh, 20px);
}

.survey-qr {
  width: clamp(80px, 14vh, 120px);
}

/* keep-all: 한글은 기본이 글자 단위 줄바꿈이라 "들려주세 / 요" 처럼
   단어 한가운데가 잘린다. 어절 단위로 넘기게 한다. */
.survey-text {
  font-size: clamp(13px, 1.7vh, 16px);
  font-weight: 500;
  line-height: 1.65;
  text-align: center;
  color: var(--ink);
  word-break: keep-all;
  overflow-wrap: break-word;
}

.toast {
  position: absolute;
  left: 50%;
  bottom: clamp(16px, 3vh, 32px);
  transform: translate(-50%, 20px);
  background: var(--ink);
  color: var(--cream);
  border-radius: 0;
  padding: 14px 24px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  white-space: nowrap;
}

.toast.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ==== 에러 ==== */

#screen-error {
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
}

.error-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(14px, 2.6vh, 24px);
  max-width: 90%;
}

.error-title {
  font-size: clamp(22px, 4vh, 32px);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.error-message {
  font-size: clamp(14px, 2.2vh, 18px);
  font-weight: 500;
  color: #666;
  line-height: 1.6;
  text-align: center;
  max-width: 34em;
}

/* 권한이 차단됐을 때 푸는 순서. 부스 담당자가 보고 따라할 수 있어야 한다. */
.error-steps {
  display: none;
  margin: 0;
  padding-left: 1.4em;
  text-align: left;
  font-size: clamp(13px, 2vh, 17px);
  font-weight: 500;
  line-height: 1.9;
  color: var(--ink);
  max-width: 34em;
}
.error-steps li { padding-left: 4px; }

/* 원인 진단용. 작게, 눈에 안 띄게. */
.error-detail {
  font-size: 12px;
  color: #999;
  letter-spacing: 0.02em;
}

/* ==== 버튼 (quiz-demo .btn/.bk/.bo/.br 톤, 키오스크용으로 확대) ==== */

/* 크기 modifier(.btn-xl)를 안 붙인 버튼도 키오스크에서 누를 만해야 한다.
   기본값이 없으면 브라우저 기본 크기로 떨어져 서서 조작하기엔 너무 작아진다. */
.btn {
  display: inline-block;
  border: none;
  border-radius: 0;
  font-family: inherit;
  font-weight: 500;
  font-size: clamp(14px, 2vh, 18px);
  padding: clamp(10px, 1.6vh, 14px) clamp(18px, 3vh, 26px);
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: opacity 0.18s ease;
}

.btn:hover { opacity: 0.82; }

/* 기본(.bk): 잉크 배경 + 크림 글자 */
/* 다시 찍기: 검정 바탕 + 흰 글씨 */
.btn-dark {
  background: var(--ink);
  color: #fff;
}

/* 강조(.bo): 오렌지 배경 + 흰 글자 */
/* 저장하기: 오렌지 바탕 + 검정 글씨 */
.btn-accent {
  background: var(--orange);
  color: var(--ink);
}

/* 보조(.br): 투명 배경 + 잉크 글자 + 얇은 테두리 */
.btn-outline {
  background: transparent;
  color: var(--ink);
  border: 1px solid rgba(0, 0, 0, 0.3);
}

.btn-xl {
  font-size: clamp(16px, 2.6vh, 22px);
  font-weight: 700;
  padding: clamp(12px, 2vh, 18px) clamp(24px, 5vh, 40px);
}

body.loading #screen-select { cursor: wait; }
body.loading .house-card { pointer-events: none; opacity: 0.6; }

/* ==== 모바일 (개인 폰) ====
   부스 아이맥은 고정 폭 컬럼이 맞지만, 폰에서는 좌우가 잘린다.
   여기서는 세로로 쌓고 스크롤을 허용한다. 폰에서 스크롤은 자연스러운 조작이다.
   100dvh 를 쓰는 이유: 100vh 는 모바일 브라우저 주소창 높이를 빼지 않아
   화면 아래가 잘린다. */
@media (max-width: 820px) {
  html, body {
    height: auto;
    overflow-y: auto;
    overflow-x: hidden;
  }

  #app {
    height: auto;
    min-height: 100vh;
    min-height: 100dvh;
    padding: 0 16px;
  }

  .screen {
    height: auto;
    min-height: 100vh;
    min-height: 100dvh;
  }

  /* #app 이 이미 좌우 16px 을 잡는다. 화면마다 또 패딩을 주면 이중이 되어
     카드가 불필요하게 좁아진다. */
  #screen-select,
  #screen-error {
    padding-left: 0;
    padding-right: 0;
  }

  /* 5장을 한 줄에 넣으면 한 장이 60px 남짓이 된다. 두 줄로 접는다. */
  .house-cards {
    flex-wrap: wrap;
    gap: 10px;
  }
  .house-card {
    flex: 0 0 calc(50% - 5px);
  }

  /* 프리뷰: 높이를 고정하면 3:2 가 화면 폭을 넘는다. 폭 기준으로 잡는다. */
  .camera-frame {
    width: 100%;
    height: auto;
    max-height: 50dvh;
  }

  /* 결과: 사진 → 버튼 → QR 순으로 세로 배치 */
  .result-inner {
    flex-direction: column;
    gap: 20px;
  }
  .result-side {
    width: 100%;
    max-width: 100%;
  }
  .result-image {
    width: auto;
    max-width: 100%;
    max-height: 52dvh;
  }
  #screen-result {
    justify-content: flex-start;
    padding: 20px 0 40px;
  }

  .idle-video { height: auto; }
}
