* { box-sizing: border-box; }

body {
  margin: 0;
  /* Pretendard. 굵기 매핑과 대체 폰트는 fonts.css에 있다 */
  font-family: var(--font-body);
  color: #1f2430;
  background: #0f1420;
  word-break: keep-all;
  overflow-wrap: break-word;
}

.page {
  min-height: 844px; /* 기준 캔버스 높이 (vh 금지 - canvas.css 참고) */
  /* 위쪽은 구름 하늘. 하늘 이미지가 끝나는 지점부터는 빌리지 장면 아래라서,
     도로 맨 아랫줄 색(#c4a39d)으로 이어붙여 도로가 페이지 끝까지 계속되게 한다.
     그 위에 흰 베일 30%를 덮어 배경을 살짝 눌렀다 (입력 폼 화면과 같은 값) */
  background-color: #c4a39d;
  background-image: linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.3)),
    url("assets/scene/sky.png");
  background-position: top center, top center;
  background-size: 100% 100%, 100% auto;
  background-repeat: no-repeat, no-repeat;
}

.host-page {
  max-width: 420px;
  margin: 0 auto;
  padding: 40px 20px 56px;
  text-align: center;
}

.hidden { display: none !important; }

.empty-state {
  padding: 80px 20px;
  text-align: center;
  color: #4d5262;
}
.empty-link {
  display: inline-block;
  margin-top: 14px;
  color: #111318;
  font-weight: 700;
  text-decoration: none;
}

/* 띠 동물 + 말풍선 한 줄. 동물은 가운데, 말풍선은 그 오른쪽 위에 겹쳐 놓는다.
   말풍선 꼬리(작은 원 두 개)가 왼쪽 아래를 향하므로 말하는 쪽이 동물이 된다. */
/* 호스트 띠 동물. 말풍선을 뺐으니 그냥 정가운데다.
   이미지에 그림자가 그려져 있어서 CSS drop-shadow는 걸지 않는다 (그림자가 두 겹이 된다).
   원본 460x495(바닥선이 12종 모두 같은 자리)라 상자도 같은 비율로 잡아야 안 눌린다. */
/* ── 매달린 간판 (assets/sign-plate.png = 디자이너 간판2, 글자 없는 빈 판) ──
   원본 993x356. 판은 y 131~354 (위 36.8% ~ 아래 100%)이고 그 위는 매다는 봉이라 비어 있다.
   글자는 판 안쪽에만 놓여야 해서, 봉 높이만큼 위를 비우고 아래 62.9%에 글자를 앉힌다. */
.host-sign {
  --sign-w: 232px;
  position: relative;
  width: var(--sign-w);
  height: calc(var(--sign-w) * 352 / 986);
  /* 매다는 봉이 화면 맨 위(y=0)에서 내려오게 한다.
     .host-page의 위 패딩 40px을 음수 마진으로 상쇄해야 캔버스 꼭대기에 닿는다. */
  margin: -40px auto 2px;
  background: url('assets/sign-plate.png') no-repeat center / 100% 100%;
}
.host-sign-text {
  position: absolute;
  left: 0;
  right: 0;
  /* 판에서 글자가 앉는 면은 위 38.1% ~ 92.6% 구간이다 (여백 잘라낸 에셋 기준).
     그 아래는 판 두께(베벨)라 면이 아니다 - 전체 높이로 가운데를 잡으면 아래로 처져 보인다.
     면 기준 가운데 65.3%. */
  top: 65.3%;
  transform: translateY(-50%);
  margin: 0;
  padding: 0 7%;
  /* 판 폭에 비례시킨다. --sign-w만 바꾸면 글자도 같이 줄어서 판 밖으로 안 넘친다
     (232px 기준 16px) */
  font-size: calc(var(--sign-w) * 0.069);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: #14171f;
  white-space: nowrap;
  overflow: hidden;
}

.host-hero {
  position: relative;
  width: 100%;
  /* 간판이 맨 위로 올라가면서 동물이 간판에 붙어 보여서 조금 내렸다 */
  margin: 18px 0 14px;
  display: flex;
  justify-content: center;
}
.host-avatar {
  width: 150px;
  height: 161px;
}
.host-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.host-name {
  margin: 0 0 18px;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: -0.015em;
  color: #4d5262;
}

.eyebrow {
  margin: 0;
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: 0.02em;
  color: #111318;
}
/* '나를 이루는 기운' 글자를 뺀 자리 - 타이틀 덩어리와 아래를 가르는 짧은 선만 남긴다.
   선 위아래 여백은 예전 라벨과 같게 맞췄다(위 22 / 아래 22 + 라벨 높이만큼). */
.host-divider {
  position: relative;
  height: 2px;
  margin: 22px auto 27px;
}
.host-divider::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 96px;
  height: 2px;
  margin-left: -48px;
  border-radius: 2px;
  background: rgba(90, 90, 120, 0.22);
}

/* 타이틀이 한 문장짜리 한글이라 별도 제목 폰트를 두지 않고,
   본문 폰트에서 크기·굵기·자간으로 위계를 만든다. */
.host-title {
  margin: 0;
  /* 23.5px/800 -> 21.5px/600 으로 내렸다가, 굵기만 700으로 다시 올렸다 */
  font-size: 21.5px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.025em;
  word-break: keep-all;
  color: #1a1a2e;
}

/* 항상 2줄로 보이게 한다. 짧아도 자리는 두 줄을 차지하고(min-height),
   길어져서 3줄이 되는 건 ELEMENT_TRAIT의 31자 상한으로 막는다. */
/* 타이틀 아래 설명 한 줄. 문구를 350px 안에 들어가게 써서 항상 1줄이다
   (넘치면 2줄이 되면서 아래 블록이 밀린다 - title-preview.html에서 폭을 재고 쓴다) */
.host-subtitle {
  margin: 0; /* 바로 위 .host-origin과 이어지는 같은 덩어리 */
  min-height: 1.5em; /* line-height x 1줄 - 행간을 바꾸면 이 값도 같이 바꾼다 */
  font-size: 14.5px;
  /* 입력 화면 서브타이틀(.subtitle)과 같은 행간. 화면을 넘겨도 글줄 간격이 안 튄다 */
  line-height: 1.5;
  letter-spacing: -0.01em;
  word-break: keep-all;
  color: #6a6f80;
}

/* 타이틀 아래 장식선. 가로로만 늘어나야 해서(preserveAspectRatio="none") 두께는
   viewBox 높이(14)로 고정되고, 폭만 화면에 맞춘다. 반짝임은 선 오른쪽 끝에 붙어 있다. */
/* 타이틀 바로 아래: 무엇으로 언제 태어났는지 (일간 한자 + 계절 + 그 자리의 성질).
   두 줄까지 가는 문장이라 아래 설명(.host-subtitle)보다 살짝 작고 연하게 둬서
   타이틀 > 근거 > 설명 순으로 읽히게 한다. */
.host-origin {
  margin: 10px 0 0;
  /* 설명 세 줄(일주 두 줄 + 성향 한 줄)은 크기·색·행간을 모두 같게 둬서 한 덩어리로 읽힌다.
     타이틀만 크게 남기고 나머지는 위계를 두지 않는다는 게 사용자 요청이다. */
  font-size: 14.5px;
  /* .host-subtitle 과 같은 값이어야 세 줄이 한 덩어리로 읽힌다 */
  line-height: 1.5;
  letter-spacing: -0.01em;
  word-break: keep-all;
  color: #6a6f80;
}

/* "어떤 기운의 주민이 귀한지"는 행동을 유도하는 문장이라 줄을 갈라 세운다 */
/* 귀한 기운 둘째 줄 - '그래서 뭘 하면 되는지'. 위 줄이 굵은 결론이라 여기는 힘을 뺀다 */
.host-precious-action {
  margin: 4px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  word-break: keep-all;
  color: #8a8f9c;
}

.host-precious {
  margin: 0; /* 바로 위 가르는 선과 한 덩어리 */
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: -0.01em;
  word-break: keep-all;
  color: #111318;
}

.guest-own-section {
  /* 카드 그림 위쪽이 집게라 여백처럼 보인다. 그래서 간판 바로 아래에 붙여도 안 답답하다 */
  margin-top: 6px;
}

/* ── 게스트 본인이 볼 때, 카드 위 인사말 ─────────────────────────
   '/'는 korean.js의 강제 줄바꿈 표시라서 JS가 setClauseText로 채운다 */
/* 카드 아래 첫 줄 - 아래 두 줄과 글꼴은 같고 형광펜만 안 칠한다 */
.own-intro-desc {
  margin: 10px 0 0;
  text-align: center;
  font-size: 14.5px;
  /* 아래 형광펜 두 줄(700)보다 한 단계 얇게 - 행동 안내가 더 도드라진다 */
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: #111318;
  word-break: keep-all;
}
/* 형광펜 치는 안내 두 줄 */
/* 줄 사이 여백 없이 행간(1.45)만으로 띄운다.
   단, 첫 줄(안내)과 형광펜 두 줄 사이는 결이 달라서 아주 조금만 벌린다 (아래 :first-of-type) */
.own-intro-guide {
  margin: 0;
  text-align: center;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: #111318;
  word-break: keep-all;
}
/* 앞뒤 홑화살괄호 - 글자보다 조금 옅게 두고 안쪽만 살짝 띄운다 */
.own-intro-desc .bk {
  color: #6a6f80;
  font-weight: 500;
}
.own-intro-desc .bk:first-child { margin-right: 3px; }
.own-intro-desc .bk:last-child { margin-left: 3px; }

/* '빌리지에 새로운 주민이 되었어요' 와 '반짝이는...' 사이만 살짝 벌린다.
   .own-intro-guide2 는 두 번째 줄이라 안 걸린다 */
.own-intro-guide:not(.own-intro-guide2) {
  margin-top: 9px;
}

/* 형광펜 - 글자 아래 절반만 옅은 파스텔로 칠한다.
   인라인 요소라 배경 기준은 줄상자(line-height)가 아니라 글자 상자(1.183em)다.
   브라우저에서 잰 값: 밑선은 글자 상자 바닥에서 0.233em 위, 한글 획은 밑선 위 0.80em ~
   아래 0.083em 에 걸친다. 그 아래 절반(0.48em)을, 획 맨 아래(= 바닥에서 0.15em)까지 칠한다.
   em 기준이라 글자 크기를 바꿔도 비율이 유지된다. */
.own-intro-guide .hl {
  background-image: linear-gradient(rgba(255, 214, 130, 0.45), rgba(255, 214, 130, 0.45));
  background-repeat: no-repeat;
  background-size: 100% 0.48em;
  background-position: 0 calc(100% - 0.15em);
}

/* 타이틀 아래 설명 첫머리의 '금(金) 일주' 형광펜.
   오행을 기준으로 빌리지가 생성된다는 걸 인지하지 못했다는 피드백에 대한 조치다.
   색은 그 빌리지의 오행 색이다 - host.js 의 applyBuilding 이 --pillar-hl 로 넣어준다.

   글자 크기·굵기·색은 건드리지 않는다. 설명 세 줄은 위계 없이 한 덩어리로 읽혀야 한다는
   기존 결정이 있어서, 강조는 밑칠로만 준다.
   밑칠 위치·높이는 위 .own-intro-guide .hl 과 같은 실측값이다 (em 기준이라 크기와 무관). */
.host-origin .pillar-hl {
  background-image: linear-gradient(var(--pillar-hl, rgba(255, 214, 130, 0.45)),
                                    var(--pillar-hl, rgba(255, 214, 130, 0.45)));
  background-repeat: no-repeat;
  background-size: 100% 0.52em;
  background-position: 0 calc(100% - 0.14em);
  /* 좌우로 조금 넘겨 칠해 형광펜으로 그은 느낌을 낸다.
     음수 마진으로 상쇄해서 글자 위치는 그대로 둔다 (줄바꿈이 달라지지 않게) */
  padding: 0 0.14em;
  margin: 0 -0.14em;
  border-radius: 2px;
}

/* ── 설문 팝업 ────────────────────────────────────────────────────
   한 번에 한 문항만 보여준다. 현장에서 서서 하는 거라 문항당 한 번만 누르면
   다음으로 넘어가고(확인 버튼 없음), 세 번 누르면 끝난다.
   .overlay-layer 안이라 높이 기준은 vh가 아니라 부모다 (canvas.css 참고). */
.survey-modal {
  position: absolute;
  inset: 0;
  z-index: 25;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(15, 20, 32, 0.55);
}
.survey-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 320px;
  max-height: 100%;
  padding: 26px 22px 22px;
  border-radius: 22px;
  background: #fff;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  animation: survey-in 0.22s ease-out;
}
@keyframes survey-in {
  from { opacity: 0; transform: translateY(10px) scale(0.97); }
  to { opacity: 1; transform: none; }
}
.survey-x {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: #9aa0ae;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  user-select: none;
}
.survey-x:active { background: #f1f2f4; }

.survey-step { display: flex; flex-direction: column; min-height: 0; }
.survey-step.hidden { display: none !important; }

.survey-heading {
  margin: 0 0 9px;
  font-size: 18px;
  font-weight: 800;
  line-height: 1.45;
  letter-spacing: -0.03em;
  color: #14171f;
  word-break: keep-all;
}
.survey-lede {
  margin: 0;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.65;
  letter-spacing: -0.01em;
  color: #6a7180;
  word-break: keep-all;
}
.survey-start {
  margin-top: 20px;
  padding: 13px;
  border: none;
  border-radius: 14px;
  background: #111318;
  color: #fff;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.02em;
  cursor: pointer;
  user-select: none;
  transition: transform 0.1s ease;
}
.survey-start:active { transform: scale(0.98); }

/* 진행 표시 - 세 칸 중 지금 칸만 길고 진하다 */
.survey-dots {
  display: flex;
  justify-content: center;
  gap: 5px;
  margin: 0 0 16px;
}
.survey-dots i {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: #dfe2e8;
  transition: width 0.2s ease, background 0.2s ease;
}
.survey-dots i.on { width: 18px; background: #111318; }
.survey-dots i.done { background: #a9b0be; }

.survey-q {
  margin: 0 0 14px;
  /* 두 줄로 접힐 때 줄 길이를 비슷하게 나눈다 - 한 줄만 길면 가운데가 안 맞아 보인다 */
  text-wrap: balance;
  font-size: 16.5px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: -0.025em;
  color: #14171f;
  word-break: keep-all;
}
.survey-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 2px;
  margin: -2px;
}
/* 보기 - 이모지를 왼쪽에 세우고 글은 왼쪽 정렬. 한 손으로 누르기 좋은 높이로 둔다 */
.survey-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 13px 14px;
  border: 1.5px solid #e6e8ee;
  border-radius: 14px;
  background: #fbfbfc;
  text-align: left;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -0.015em;
  color: #2a2f3d;
  cursor: pointer;
  user-select: none;
  word-break: keep-all;
  transition: transform 0.1s ease, border-color 0.15s ease, background 0.15s ease;
}
.survey-opt em {
  flex: 0 0 auto;
  font-style: normal;
  font-size: 19px;
  line-height: 1;
}
.survey-opt:active { transform: scale(0.985); }
/* 고른 보기 - 다음 문항으로 넘어가기 전 한 박자만 보여준다 */
.survey-opt.picked {
  border-color: #111318;
  background: #111318;
  color: #fff;
}

/* 별점 문항 - 보기 버튼 대신 별 5개.
   보기 목록과 달리 세로로 쌓지 않으니, 남는 높이를 위아래 여백으로 돌린다 */
.survey-options.is-stars {
  justify-content: center;
  align-items: center;
  gap: 0;
  overflow: visible;
  padding: 6px 2px 2px;
}
.survey-stars {
  display: flex;
  gap: 6px;
  justify-content: center;
}
.survey-star {
  border: 0;
  background: none;
  padding: 2px 3px;
  font-size: 40px;
  line-height: 1;
  /* 꺼진 별은 테두리만 남은 것처럼 옅게 둔다 (별 글자 하나로 두 상태를 만든다) */
  color: #dfe2e9;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.12s ease, transform 0.12s ease;
}
.survey-star.on { color: #ffc23d; }
.survey-star:active { transform: scale(0.92); }
.survey-star:focus-visible { outline: 2px solid #111318; outline-offset: 2px; border-radius: 6px; }
.survey-star-hint {
  margin: 10px 0 0;
  min-height: 20px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: #6b7280;
  text-align: center;
}

/* 완료 화면 - 글자 두 줄과 버튼뿐이라 카드를 한 단계 좁게 */
.survey-card.compact {
  max-width: 264px;
  padding: 24px 20px 18px;
}
.survey-card.compact .survey-heading { font-size: 17px; margin-bottom: 7px; }
.survey-card.compact .survey-lede { font-size: 13px; }
.survey-card.compact .survey-start { margin-top: 16px; padding: 11px; font-size: 15px; }

/* 손 흔드는 이모지 - 두어 번 흔들고 쉬었다가 다시 흔든다.
   손목(오른쪽 아래)을 축으로 돌려야 인사하는 것처럼 보인다 */
.wave-hand {
  display: inline-block;
  margin-left: 3px;
  transform-origin: 72% 82%;
  animation: hand-wave 2.4s ease-in-out infinite;
}
@keyframes hand-wave {
  0%, 52%, 100% { transform: rotate(0deg); }
  58% { transform: rotate(15deg); }
  66% { transform: rotate(-11deg); }
  74% { transform: rotate(15deg); }
  82% { transform: rotate(-9deg); }
  90% { transform: rotate(9deg); }
}

/* ── 입주 등록증 ─────────────────────────────────────────────────
   디자이너 최종본 PNG(1101x752)가 카드 판이다. 그림에는 유리·집게·로고·바코드만 남기고
   글자는 전부 지운 뒤 여기서 프리텐다드로 다시 쓴다 - 디자이너가 굵기/크기를 지정했기 때문이다.
   좌표는 전부 원본 픽셀 / 1101(가로) · 752(세로) 비율이다.
   숫자를 바꿀 일이 있으면 원본에서 다시 재는 게 빠르다. */
.resident-card {
  position: relative;
  /* 게스트 화면에서는 맨 위에 온다 */
  margin-top: 0;
  text-align: left;
}
.rc-art { display: block; width: 100%; height: auto; }

/* 캐릭터 - 원본 캐릭터 자리(x106~319, y322~671)에 맞춰 바닥으로 정렬한다.
   입주민 스프라이트(240x284)는 원본 크롭보다 넓적해서 폭이 아니라 키를 맞췄다. */
.rc-photo {
  position: absolute;
  left: 6.3%;
  width: 26%;
  bottom: 10.77%;
  height: 47%;
}
.rc-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom center;
  filter: drop-shadow(0 4px 6px rgba(40, 55, 80, 0.18));
}

/* 카드 종류 - 세미볼드 12 */
.rc-kind {
  position: absolute;
  right: 7.08%;
  top: 31.71%;
  transform: translateY(-50%);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1;
  color: #111114;
  white-space: nowrap;
}

/* 항목 - 둘 다 10px. 라벨은 라이트(300), 값은 볼드(700) */
.rc-l,
.rc-v {
  position: absolute;
  transform: translateY(-50%);
  font-size: 10px;
  line-height: 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.rc-l {
  left: 35.24%;
  font-weight: 300;
  color: #3a3a3f;
}
.rc-v {
  right: 27.97%;
  font-weight: 700;
  color: #111114;
}
.rc-r1 { top: 49.20%; }
.rc-r2 { top: 58.05%; }
.rc-r3 { top: 66.90%; }
.rc-r4 { top: 75.75%; }

/* 궁합 점수 - 라벨 레귤러 8, 숫자 엑스트라볼드 32.
   숫자 색은 점수마다 달라서 host.js가 넣는다 */
.rc-score-label {
  position: absolute;
  left: 87.6%;
  top: 73.80%;
  transform: translate(-50%, -50%);
  font-size: 8px;
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1;
  color: #111114;
  white-space: nowrap;
}
.rc-score {
  position: absolute;
  left: 87.8%;
  top: 83.18%;
  transform: translate(-50%, -50%);
  font-size: 32px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  white-space: nowrap;
}

.recruit-card {
  margin-top: 24px;
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 18px;
  padding: 16px 18px 14px;
  box-shadow: 0 12px 26px rgba(30, 30, 60, 0.1);
}
.recruit-heading {
  margin: 0 0 5px;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: -0.02em;
  color: #1a1a2e;
}
/* 초대할 이유를 만들어주는 한 줄. 배경 없이 작게 두고 느낌표만 눈에 걸리게 한다 */
.recruit-point {
  margin: 0 0 12px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: #5c6068;
  white-space: nowrap;
}
.recruit-cta {
  width: 100%;
  padding: 12px;
  border: none;
  border-radius: 14px;
  background: #111318;
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.02em;
  cursor: pointer;
  box-shadow: 0 10px 20px rgba(17, 19, 24, 0.24);
  transition: transform 0.1s ease;
}
.recruit-cta:active { transform: scale(0.98); }
/* 복사 결과 안내. 평소엔 비어 있어서 자리를 미리 잡아두지 않는다 -
   min-height로 한 줄을 비워두면 버튼 아래에 흰 공간이 계속 남는다.
   문구가 뜰 때 카드가 한 줄만큼 늘어나는데, 몇 초 지나면 사라지는 문구라 그대로 뒀다. */
.copy-hint {
  margin: 0;
  font-size: 13.5px;
  color: #111318;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: -0.01em;
}
.copy-hint:not(:empty) { margin-top: 8px; }
/* 복사가 막히는 환경(휴대폰 http 접속)에서만 링크가 여기 뜬다.
   평소에는 복사 성공 문구만 짧게 지나간다. */
.copy-hint.copy-hint-url {
  padding: 8px 10px;
  border-radius: 8px;
  background: #f3f4f6;
  text-align: left;
}
.copy-hint.copy-hint-url b {
  display: block;
  margin-bottom: 3px;
  font-size: 11.5px;
  font-weight: 700;
  color: #7d818c;
  user-select: none;
}
.copy-hint.copy-hint-url a {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.5;
  color: #111318;
  word-break: break-all;
  text-decoration: underline;
  text-underline-offset: 2px;
  /* 한 번 탭하면 주소 전체가 선택된다 */
  user-select: all;
  -webkit-user-select: all;
}

/* 캔버스 폭 전체로 빼낸다 - 하늘·도로가 화면 끝까지 이어지도록 (.host-page 좌우 패딩 20px 상쇄) */
.village-section { margin: 30px -20px 0; }

/* 문장부호로 끊은 조각. inline-block이라 조각이 통째로 다음 줄로 넘어가서
   한 문장이 두 줄로 잘리지 않는다. 조각이 줄보다 길면 그 안에서만 접힌다. */
.clause {
  display: inline-block;
  word-break: keep-all;
}

/* 바이럴: 아파트를 다 구경한 뒤 맨 아래에서 자기 빌리지를 만들러 가게 한다 */
/* 설문 - 아파트를 다 본 뒤 맨 아래. 상자 전체가 버튼이라
   따로 CTA를 두지 않는다 (아래 '내 빌리지 만들기'가 진짜 CTA라 여기는 무게를 낮춘다) */
.survey-box {
  /* 건물 아래 도로가 111px쯤 남는데(건물이 인도 위에 서게 하려고 비워둔 자리),
     그만큼 흰 상자가 멀어 보였다. 상자를 도로 위로 끌어올려 간격을 반으로 줄인다.
     - 도로 자체를 줄이면 건물이 인도를 벗어나 길 앞에 선 것처럼 된다 (그래서 안 건드린다) */
  position: relative;
  z-index: 1;
  margin-top: -45px;
  padding: 18px 20px 16px;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 10px 24px rgba(30, 30, 60, 0.08);
  text-align: center;
}
.survey-box-title {
  margin: 0;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: -0.025em;
  color: #14171f;
  word-break: keep-all;
}
.survey-box-sub {
  margin: 5px 0 0;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.55;
  letter-spacing: -0.01em;
  color: #6a7180;
  word-break: keep-all;
}
/* 시작 CTA - 아래 '내 빌리지 만들기'가 진짜 CTA라 여기는 테두리만 있는 버튼으로 둔다 */
.survey-box-cta {
  width: 100%;
  margin-top: 13px;
  padding: 12px;
  border: 1.5px solid #111318;
  border-radius: 14px;
  background: transparent;
  color: #111318;
  /* '내 빌리지 만들기'(.make-mine-cta)보다 한 급 작다 - 문구가 길어서
     17px 로는 버튼을 꽉 채워 답답해 보인다 */
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.02em;
  cursor: pointer;
  /* 현장에서 연타하면 글자가 선택돼 파랗게 보인다 */
  user-select: none;
  -webkit-user-select: none;
  transition: transform 0.1s ease;
}
.survey-box-cta:active { transform: scale(0.98); }

.make-mine-section {
  margin-top: 12px;
  padding: 22px 20px;
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 10px 24px rgba(30, 30, 60, 0.1);
  text-align: center;
}
.make-mine-desc {
  margin: 0 0 12px;
  /* 위 설문 상자 제목(.survey-box-title)과 같은 글씨로 맞췄다 - 두 카드가 한 세트로 읽히게 */
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: -0.025em;
  color: #14171f;
  word-break: keep-all;
}
.make-mine-cta {
  display: block;
  padding: 14px;
  border-radius: 14px;
  background: #111318;
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.02em;
  text-decoration: none;
  box-shadow: 0 10px 20px rgba(17, 19, 24, 0.24);
  transition: transform 0.1s ease;
}
.make-mine-cta:active { transform: scale(0.98); }



/* ── 빌리지 장면: 하늘 + 도로 + 그 위에 선 아파트 ──────────────────
   층이 늘어나면 .village-scene 이 함께 길어진다. 하늘은 "아래(수평선) 기준"으로
   깔아서 위로 늘어나고(그래서 5층이든 12층이든 수평선 위치가 안 흔들린다),
   도로는 항상 장면 맨 아래에 붙는다. 건물이 "핑크 인도 위"에 서도록
   장면 아래에 223/780 = 28.6% 만큼 도로를 남겨둔다 - 인도 띠(도로 이미지 y 175~301)의
   가운데쯤이 건물이 서는 선이다. 연석선(y=301)에 세우면 인도가 건물에 다 가려서
   길 위가 아니라 길 앞에 서 있는 것처럼 보인다. */
.village-scene {
  position: relative;
  padding-bottom: 28.6%;
}
.village-scene::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  /* 하늘은 폭에 맞춰(100% auto) 아래(수평선) 기준으로 깔고, 그 위로 남는 공간은
     하늘 이미지 맨 윗줄 색을 세로로 늘린 띠(sky-top)로 채운다.
     cover로 늘리면 층이 많아질수록 구름이 확대·잘려서 어색해지는데, 이 방식은
     층수가 몇이든 구름 크기가 그대로다. */
  background-color: #a3c4d3;
  /* 맨 위 레이어가 흰 베일 30% - 페이지 배경과 같은 값이라 경계가 안 보인다 */
  background-image: linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.3)),
    url("assets/scene/sky.png"), url("assets/scene/sky-top.png");
  background-position: top center, bottom center, top center;
  background-size: 100% 100%, 100% auto, 100% 100%;
  background-repeat: no-repeat, no-repeat, no-repeat;
  /* 위쪽 여백(페이지 배경)에서 장면 하늘로 부드럽게 넘어가게 - 경계선이 보이지 않도록 */
  -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0, #000 96px);
  mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0, #000 96px);
}
.scene-road {
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  width: 100%;
  z-index: 0;
}
/* 도로도 배경이므로 같이 눌러준다. 건물(z-index 1)은 이 위라서 선명하게 남는다 */
.scene-road-veil {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  aspect-ratio: 780 / 456;  /* road.png 비율 - img와 정확히 겹친다 */
  background: rgba(255, 255, 255, 0.3);
  z-index: 0;
  pointer-events: none;
}

.village-image-wrap {
  position: relative;
  z-index: 1;
}
.village-image {
  display: block;
  width: 100%;
  height: auto;
}

/* 지붕(현관) 중앙에 사는 호스트 띠 캐릭터 */
.roof-wrap { position: relative; }
/* 옥상 에셋 5장은 전부 1446x713이라, 로딩 전에도 자리를 잡아둬서
   벽이 아래로 밀리지 않게 한다 */
.roof-wrap .village-image { aspect-ratio: 1446 / 713; }
/* 옥상(다락) 바닥 = 지붕 이미지 713px 중 707px 지점. 그 위에 서게 맞춘다.
   폭 19%면 동물 키가 옥상 문 높이와 비슷해져서 공간에 자연스럽게 들어찬다. */
.host-in-roof {
  position: absolute;
  left: 50%;
  bottom: 0.84%;
  width: 19%;
  aspect-ratio: 1;
  transform: translateX(-50%);
  z-index: 2;
}
.host-in-roof img {
  /* inline이면 글꼴 디센더만큼(약 4px) 아래 여백이 생겨서 캐릭터가 데크 위에 떠 보인다 */
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.35));
}

.village-overlay-top {
  position: absolute;
  top: 12px;
  left: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  z-index: 2;
}
.occupancy-badge {
  padding: 7px 14px;
  border-radius: 999px;
  background: rgba(20, 30, 30, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.01em;
}
.download-btn {
  width: 34px;
  height: 34px;
  border: none;
  border-radius: 50%;
  /* 누를 수 있는 것은 다른 CTA(초대 링크 복사하기 등)와 같은 검정으로 둔다.
     반투명이던 때는 배경 그림에 따라 밝기가 달라 눌러도 되는지 애매했다.
     불투명이라 backdrop-filter 는 더 필요없다. */
  background: #111318;
  box-shadow: 0 6px 14px rgba(17, 19, 24, 0.28);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  font-size: 17px;
  cursor: pointer;
  padding: 0;
  transition: transform 0.12s ease, background 0.12s ease;
}
/* 이모지(⬇)를 쓰면 휴대폰에서 컬러 이모지로 바뀐다. 흰 선으로 직접 그린다. */
.download-btn svg {
  display: block;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: #fff;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.download-btn:active { transform: scale(0.92); background: #2a2f3a; }
.download-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* ── 건물 조립 (최종 아파트 5종에서 잘라낸 키트) ────────────────
   지붕+옥상 1장(1446x713) + 벽 한 층 1장(1446x324, 세로 반복) + 기단부 1장(1446x82)으로
   쌓고, 입주한 칸에만 '열린 창(빈 방)' 163x207 을 덮는다.
   닫힌 창은 벽 이미지에 이미 그려져 있어서 따로 얹지 않는다.
   모든 좌표가 1446px 기준폭에 대한 비율이라 컨테이너 폭이 390이든 420이든 그대로 맞는다. */
.floors {
  position: relative;
  z-index: 1;
  /* 새 키트는 지붕과 벽이 겹치지 않는다 (y=713에서 딱 이어진다) */
  margin-top: var(--roof-overlap, 0);
}
.floor { position: relative; }
/* 건물 최하단 기단부 - 마지막 층 아래에 한 번만 깔린다 */
.village-base { display: block; width: 100%; }
.floors img { display: block; width: 100%; }

/* 창문 한 세트가 놓이는 박스. 열림/닫힘이 같은 박스를 쓰기 때문에
   상태가 바뀌어도 좌표는 그대로다. 클릭 영역도 이 박스와 정확히 같다. */
.floors .win {
  position: absolute;
  width: 11.2725%;  /* 163 / 1446 */
  top: 20.6790%;    /* 67 / 324 */
  height: 63.8889%; /* 207 / 324 */
  z-index: 1;
}
.floors .win[data-col="1"] { left: 10.1660%; }  /* 147 / 1446 */
.floors .win[data-col="2"] { left: 27.1093%; }  /* 392 / 1446 */
.floors .win[data-col="3"] { left: 43.9834%; }  /* 636 / 1446 */
.floors .win[data-col="4"] { left: 60.9959%; }  /* 882 / 1446 */
.floors .win[data-col="5"] { left: 78.0083%; }  /* 1128 / 1446 */

.floors .win.open { cursor: pointer; }
/* 열린 창 = 셔터가 걷힌 빈 방. 창문 박스를 그대로 덮고, 입주민이 그 안에 선다 */
.floors .win .room {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
/* 입주민은 방 안에 바닥을 딛고 선다 (위가 잘리지 않게 contain + 아래 정렬) */
.floors .win .avatar {
  position: absolute;
  z-index: 1;
  /* 사람 크기는 height(82%)가 정한다. 아래끝(10.8+82 = 92.8%)은 **창문 하단 흰 틀의 윗선** -
     100%까지 내리면 사람이 그 흰 틀을 덮어버린다(오행별로 92.8%(목·수·토)/94.7%(금·화)라 작은 쪽).

     폭 88%는 눈대중이 아니라 계산값이다: 입주민 스프라이트가 240x284(비율 0.845)이므로
     박스 높이 82%(169.7px)에 맞는 폭은 169.7 x 0.845 = 143.4px = 창문 폭의 88%.
     **박스 비율을 스프라이트 비율과 같게 맞춰야 머리카락·어깨가 좌우로 안 잘린다.**
     전에는 폭 64%(비율 0.615)여서 세로에 맞춰 커진 그림이 좌우로 27%씩 잘려나갔다.
     스프라이트 비율이 바뀌면 이 폭도 다시 계산해야 한다 (contain이라 안 맞으면 잘리는 대신 작아진다). */
  left: 6%;
  width: 88%;
  top: 10.8%;
  height: 82%;
  object-fit: contain;
  object-position: bottom;
}

/* 내가 방금 입주한 창문 - 반짝이며 눌러보라고 유도 */
.floors .win.is-me {
  z-index: 2;
  /* 크기만 커졌다 작아지던 것에 빛 세기까지 같이 태운다. 입주 완료 후 이 창문을
     눌러야 궁합이 열리는데 눌러야 할 것으로 안 보인다는 피드백이 있었다.
     빛은 box-shadow 라 옆 창문을 밀지 않는다 (레이아웃에 영향이 없다). */
  animation: sparkle-pulse 1.5s ease-in-out infinite;
}
@keyframes sparkle-pulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 3px #ffd54f, 0 0 16px 4px rgba(255, 213, 79, 0.7);
  }
  50% {
    transform: scale(1.1);
    box-shadow: 0 0 0 4px #ffe484,
                0 0 30px 10px rgba(255, 213, 79, 0.95),
                0 0 56px 20px rgba(255, 213, 79, 0.45);
  }
}
/* 기기에서 '움직임 줄이기'를 켠 경우. 깜빡임 없이도 눌러야 할 것으로 보이게
   가장 밝은 상태로 세워 둔다 (표지 로고와 같은 방침 - landing.css 참고) */
@media (prefers-reduced-motion: reduce) {
  .floors .win.is-me {
    animation: none;
    box-shadow: 0 0 0 4px #ffe484,
                0 0 30px 10px rgba(255, 213, 79, 0.95),
                0 0 56px 20px rgba(255, 213, 79, 0.45);
  }
}

/* 호스트가 아직 확인 안 한 새 입주민 - 창문 모서리에 작은 배지 */
.floors .win .new-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #ff5a5f;
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(255, 90, 95, 0.5);
  z-index: 2;
}

/* ── 게스트 클릭 모달 (궁합 + 가치관 + 메시지) ── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(15, 20, 32, 0.55);
}
.modal-card {
  position: relative;
  width: 100%;
  max-width: 380px;
  /* 팝업 레이어가 화면 크기라서 %가 곧 화면 비율이다. 내용이 길면 안에서 스크롤된다 */
  max-height: 85%;
  overflow-y: auto;
  background: #fff;
  border-radius: 20px;
  padding: 28px 22px 22px;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25);
}

/* 길게 눌러 저장하는 화면. 자동 저장이 막힌 기기에서만 뜬다.
   빌리지 그림은 세로로 길어서(최대 1446 x 수천px) 카드 안에서 스크롤되게 둔다. */
.save-image-card {
  padding: 44px 14px 14px;
}
.save-image-guide {
  margin: 0 0 12px;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: -0.015em;
  color: #2a2f3d;
}
.save-image-guide b { font-weight: 800; }
/* canvas.css 가 `.overlay-layer img` 에 길게 누르기·선택·클릭을 전부 막아 두었다
   (화면 조각이 저장되는 것을 막으려고). 이 그림은 "길게 눌러 저장" 이 목적이므로
   선택자를 같은 무게로 맞춰 여기서만 되살린다. 셋 다 풀어야 메뉴가 뜬다. */
.overlay-layer .save-image-preview {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 12px;
  -webkit-touch-callout: default;
  -webkit-user-select: auto;
  user-select: auto;
  -webkit-user-drag: auto;
  pointer-events: auto;
}

.modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: #f1f0f5;
  color: #4d5262;
  font-size: 14.5px;
  cursor: pointer;
}
/* 캐릭터는 배경 없는 상반신 컷아웃이라 원형으로 자르면 어깨가 날아간다.
   컷아웃 비율(160:254) 그대로 두고 그림자만 줘서 상반신 전체가 보이게 한다. */
/* 캐릭터 + 궁합 말풍선을 한 덩어리로 묶어 가운데 정렬한다.
   점수를 따로 원형으로 띄워두면 캐릭터와 따로 놀아서, 캐릭터가 말하듯 옆에 붙인다. */
.modal-hero {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 0 0 10px;
}

.modal-avatar {
  width: 72px;
  height: 114px;
  margin: 0;
  flex: 0 0 auto;
}
.modal-avatar img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom;
  filter: drop-shadow(0 8px 12px rgba(30, 30, 60, 0.22));
}
.modal-name {
  margin: 0 0 6px;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.025em;
  color: #1a1a2e;
}
.modal-bubble {
  position: relative;
  flex: 0 0 auto;
  padding: 11px 18px 13px;
  border-radius: 18px;
  background: #111318;
  color: #fff;
  text-align: center;
  box-shadow: 0 10px 20px rgba(17, 19, 24, 0.24);
}
/* 캐릭터 쪽을 향한 꼬리 */
.modal-bubble::before {
  content: '';
  position: absolute;
  left: -7px;
  top: 50%;
  transform: translateY(-50%);
  border-style: solid;
  border-width: 8px 8px 8px 0;
  border-color: transparent #111318 transparent transparent;
}
/* 누가 보느냐에 따라 '나와의 궁합' / '{호스트}와의 궁합'으로 바뀐다 */
.modal-bubble-label {
  margin: 0 0 1px;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0;
  color: rgba(255, 255, 255, 0.82);
  white-space: nowrap;
}
.modal-bubble-score {
  font-size: 30px;
  font-weight: 800;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.modal-interpretation {
  margin: 0 0 18px;
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.75;
  letter-spacing: -0.01em;
  color: #2a2f3d;
}
.modal-section-label {
  margin: 16px 0 8px;
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: 0.01em;
  color: #111318;
  text-align: left;
}
.modal-section-label:first-of-type { margin-top: 0; }
.modal-own-title {
  margin: 0 0 4px;
  font-size: 17px;
  font-weight: 800;
  color: #1a1a2e;
  text-align: left;
  line-height: 1.4;
}
.modal-own-subtitle {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: #4d5262;
  text-align: left;
}
/* 답 문구가 최대 15자라 두 개를 한 줄에 못 넣는다. 한 줄에 하나씩 쌓는다. */
.value-tags {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin: 0 0 18px;
}
/* 질문 앞자리를 위에, 답을 아래에 둔다.
   예전에는 왼쪽 84px에 질문, 오른쪽에 답을 놓았는데 답 칸이 188px밖에 안 돼서
   문장형 문구(최대 24자)의 40%가 두 줄로 접혔다. 위아래로 쌓으면 답이 306px를
   다 써서 전부 한 줄에 들어간다. */
.value-tag {
  display: block;
  width: 100%;
  padding: 8px 12px 9px;
  border-radius: 10px;
  background: #f3f4f6;
  color: #2f3242;
  font-size: 14px;
  font-weight: 700;
  /* 모달 본문이 가운데 정렬이라 상속을 끊는다 */
  text-align: left;
  word-break: keep-all;
}
/* 질문 앞자리가 없는 예전 게스트는 문구만 뜬다 (b가 비어 있어도 레이아웃이 안 깨진다) */
.value-tag.plain { padding-top: 9px; }
/* 질문은 거들 뿐이라 답보다 약하게. 한 줄을 차지하고 답 위에 앉는다 */
.value-tag b {
  display: block;
  margin-bottom: 1px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.01em;
  color: #7d818c;
}
.value-tag i {
  display: block;
  font-style: normal;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: -0.01em;
}
/* 375px에서는 두 열이 한 줄에 다 들어간다(80개 조합 전수 확인). 그보다 좁으면 답 칸이
   9자밖에 안 되어 어중간하게 접히므로, 질문을 위로 올려 "질문 한 줄 + 답 한 줄"로 만든다. */
/* 360px 미디어쿼리는 없앴다 - 캔버스가 항상 390px이라 화면 폭에 따라
   내부 레이아웃이 바뀌면 안 된다 (고정 캔버스 + 전체 스케일링 방식) */
.modal-message-section { text-align: left; }
.modal-message-readonly {
  margin: 0;
  padding: 12px 14px;
  border-radius: 12px;
  background: #faf9fc;
  font-size: 14.5px;
  color: #2a2f3d;
  line-height: 1.5;
  min-height: 20px;
}
.modal-message-section textarea {
  width: 100%;
  min-height: 80px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid #dfe1e8;
  font-family: inherit;
  font-size: 15.5px;
  resize: vertical;
  box-sizing: border-box;
}
/* 원래 landing.css의 .submit-btn을 쓰고 있었는데 host.html은 landing.css를 안 불러온다.
   스타일이 아예 안 걸려 브라우저 기본 버튼으로 나오던 걸 초대 CTA와 같은 결로 맞춘다. */
.modal-save-btn {
  width: 100%;
  margin-top: 10px;
  padding: 13px;
  border: none;
  border-radius: 14px;
  background: #111318;
  color: #fff;
  font-family: inherit;
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 8px 16px rgba(17, 19, 24, 0.22);
  transition: transform 0.1s ease, background 0.15s ease;
}
.modal-save-btn:active { transform: scale(0.98); }
.modal-save-btn:focus-visible { outline: 2px solid #111318; outline-offset: 2px; }
.modal-save-btn:disabled {
  background: #c9cbd0;
  box-shadow: none;
  cursor: default;
}

/* 게스트 뷰의 'MY 캐릭터'도 상반신 컷아웃 - 자르지 않고 전체를 보여준다 */
.host-avatar.person-avatar {
  width: 104px;
  height: 165px;
}
.host-avatar.person-avatar img {
  object-fit: contain;
  object-position: bottom;
}

/* ── 오행 소품: 게스트 일간의 오행에 맞는 물건을 창턱에 올려둔다 ──
   새 창문 박스는 그 자체가 개구부라, 방 바닥(박스 밑면)에 붙여 놓는다.
   왼쪽으로 붙여서 캐릭터 얼굴·몸통을 가리지 않게 한다. */
.floors .win .sill-item {
  position: absolute;
  left: 3%;
  bottom: 3%;
  /* 창문 폭의 42%. 26%는 축소된 화면에서 뭔지 알아보기 어려웠다 (사용자가 이 크기로 선택) */
  width: 42%;
  z-index: 2;
  pointer-events: none;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.4));
}

/* 모달 안 오행 배지 */
.modal-element {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  padding: 8px 12px;
  border-radius: 12px;
  background: #f4f5f7;
  text-align: left;
}
.modal-element:empty { display: none; }
.modal-element img {
  width: 34px;
  height: 34px;
  object-fit: contain;
  flex-shrink: 0;
}
.modal-element span {
  font-size: 14px;
  color: #4d5262;
}
.modal-element b {
  color: #111318;
  font-weight: 800;
}

/* 호스트에게 부족한 오행을 가진 게스트 = 귀한 입주민 */
.modal-element.is-precious {
  background: #fff7e6;
  box-shadow: inset 0 0 0 1px #f0d9a8;
}
.modal-element em {
  display: block;
  margin-top: 2px;
  font-style: normal;
  font-size: 13.5px;
  font-weight: 700;
  color: #b3671b;
}

/* ── 토스트 ────────────────────────────────────────────────────
   .overlay-layer 안이라 inset:0 만으로 화면 정중앙에 온다 (canvas.css 참고).
   모달(z-index 없음, 문서 순서상 앞)보다 뒤에 있으니 자연히 위로 올라온다. */
.toast {
  position: absolute;
  inset: 0;
  /* 모달(z-index 20) 위로. 안 주면 모달 카드에 가린다 */
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.toast span {
  max-width: 250px;
  padding: 13px 20px;
  border-radius: 14px;
  background: rgba(17, 19, 24, 0.92);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: -0.02em;
  text-align: center;
  word-break: keep-all;
  box-shadow: 0 12px 28px rgba(17, 19, 24, 0.3);
  /* 뜰 때만 살짝 커지며 나타난다 */
  animation: toast-in 0.18s ease-out;
}
.toast.toast-out span { animation: toast-out 0.25s ease-in forwards; }
@keyframes toast-in {
  from { opacity: 0; transform: scale(0.92); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes toast-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* 한마디 남은 글자. maxlength 만 걸면 왜 더 안 써지는지 몰라 답답하다 */
.msg-count {
  margin: 6px 2px 0;
  text-align: right;
  font-size: 12px;
  color: #8a8f9c;
}
.msg-count.is-full { color: #c2564a; font-weight: 700; }

/* 보기 문구. 두 줄이 될 수 있어 남는 폭을 다 쓰게 둔다
   (이모지는 고정 폭이고 이쪽이 늘어난다) */
.survey-opt .opt-label { flex: 1 1 auto; }

/* ── 다크 모드를 "우리가 직접 처리한다" 고 선언한다 ──────────────────
   landing.css 의 같은 블록과 같은 목적이다 (거기 설명 참고).
   color-scheme: only light 를 삼성 인터넷이 무시하고 페이지를 어둡게 만들어서,
   다크 테마가 있다고 알려 자동 반전을 멈추게 한다.

   !! 값은 위(라이트)와 반드시 같아야 한다. 다르게 적으면 다크 모드 기기에서만
      화면이 달라진다. 위쪽 색을 고치면 여기도 같이 고쳐야 한다. */
@media (prefers-color-scheme: dark) {
  body {
    color: #1f2430;
    background: #0f1420;
  }
  .page {
    background-color: #c4a39d;
    background-image: linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.3)),
      url("assets/scene/sky.png");
  }
  /* 두 카드는 라이트에서 값이 다르다 - 같이 묶어 #fff 로 적었더니 모집 박스가
     다크 모드를 켠 기기에서만 불투명해졌다. 각자 라이트와 같은 값으로 돌린다. */
  .recruit-card {
    background-color: rgba(255, 255, 255, 0.86);
  }
  .modal-card {
    background-color: #fff;
  }
}

/* ── 빈 창문 덜컹 ───────────────────────────────────────────────
   빈 칸에도 닫힌 창문 한 장을 덧대 두고(host.js 참고), 누르면 흔든다.
   !! 반드시 '커지면서' 흔들어야 한다. 벽 이미지에 같은 창문이 그려져 있어서,
      제자리에서 밀거나 작아지면 그 원본이 가장자리로 드러난다.
      scale 1.055 면 가로로 4.5px 여유가 생기므로 2px 흔들림은 덮인다. */
/* 평소엔 숨겨 둔다. 벽에 그려진 원본이 그대로 보이므로 겹침·어긋남 걱정이 없고,
   흔드는 동안에만 나타나 원본을 덮는다. */
.floors .win.empty { cursor: pointer; z-index: 0; opacity: 0; }
.floors .win.empty.rattle { opacity: 1; }
.floors .win.empty.rattle {
  animation: win-rattle 0.34s ease-out;
  transform-origin: 50% 50%;
  z-index: 2;   /* 흔드는 동안만 위로 올린다 */
}
/* !! translate 는 px 이 아니라 % 로 준다. 화면에서 창문은 44px 밖에 안 돼서
      px 로 적으면 scale 로 벌어 둔 여유보다 커져 아래 원본이 드러난다.
      지켜야 하는 관계: 흔드는 폭(%) <= 50 x (scale - 1).
      아래 값은 scale 1.045 -> 여유 2.25%, 흔들림 2% 로 그 안에 든다. */
@keyframes win-rattle {
  0%   { transform: scale(1) translateX(0); }
  18%  { transform: scale(1.045) translateX(-2%); }
  42%  { transform: scale(1.045) translateX(2%); }
  68%  { transform: scale(1.035) translateX(-1.2%); }
  100% { transform: scale(1) translateX(0); }
}
/* 기기에서 '움직임 줄이기'를 켜면 흔들지 않는다. 대신 한 번 밝아졌다 돌아온다 */
@media (prefers-reduced-motion: reduce) {
  .floors .win.empty.rattle { animation: win-blink 0.4s ease-out; }
  @keyframes win-blink {
    0%, 100% { filter: none; }
    50% { filter: brightness(1.18); }
  }
}

/* 초대 링크 안내. 주소창 링크와 초대 링크가 다르다는 걸 버튼 누르기 전에 알린다.
   위 줄(.recruit-point)과 결이 다른 '주의' 라서, 점선으로 한 번
   끊고 조금 진하게 둔다. 한 줄에 들어오는 길이다(13px 에서 약 270px / 가용 293px). */
.recruit-warn {
  margin: 0 0 11px;
  padding-top: 10px;
  border-top: 1px dashed rgba(17, 19, 24, 0.16);
  /* 글꼴·색 모두 '해당 기운을 가진 주민을~' 줄(.host-precious-action)과 같은 값이다 */
  font-size: 13.5px;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: #8a8f9c;
  word-break: keep-all;
}
