/* ============================================================
   도깨비 마을 — 전체배경(풀블리드) 레이아웃
   2026-08-22 사람 직접 지시:
     "첫 마을씬도 전체 화면을 이미지가 배경으로 들어가고 각 버튼이 그위에 올라가는 형태로 변경"
   ------------------------------------------------------------
   ★ 이 파일은 **덮어쓰기 전용**이다. village.css / village.js 는 손대지 않는다.
     head 의 맨 마지막에 실려서 village.css · bgm-player.css 규칙을 뒤에서 이긴다
     (같은 특이도면 뒤가 이긴다 — bgm-player.css:55 의 .village-back 여백도 여기서 되돌린다).

   ★ 왜 [상자째 키워 넘치게] 인가 (이 작업의 핵심)
     .shop 히트박스·.vg-light 광원·.vg-fountain 물결·village.js DOORS 는 좌표가 전부
     **원화 그림 기준 %** 다(index.html:91~131). 상자는 화면 비율인데 그림만
     object-fit:cover 로 잘리면 % 가 건물에서 어긋나 [상점을 눌렀는데 딴 데가 눌린다].
     그래서 `.village-map` **상자 자체**를 원화 비율(1024:1536)로 키워 화면 밖으로
     넘치게 하고, 넘친 부분은 화면(html)이 자른다. 크기는 village-fullbleed.js 가 px 로 준다.
     같은 기법의 선례: shop-inyeondang.css `.iy-art` / shop-inyeondang.js 자리맞추기().

   ★ transform 을 쓰지 않는다. `mix-blend-mode:screen` 인 광원 레이어(.vg-lights)는
     새 스택 문맥이 하나 끼면 [그림]이 아니라 [바탕]에 섞여 밤 조명이 타 버린다
     (village-shop.js:24~31 이 같은 이유로 카메라를 한 겹만 둔다).
     그래서 자리·크기는 width/height/left/top 으로만 준다.

   ★ 색을 새로 만들지 않았다. 그림 위에 뜨는 UI 색은 이 프로젝트에 이미 있는
     [그림 위 UI] 색 언어를 그대로 쓴다:
        바탕 rgba(20,15,40,.5)      ← village.css:275 .village-daynight
        테두리 rgba(255,255,255,.45) ← village.css:275
        글자 #fff                    ← village.css:277
        보조글자 rgba(255,255,255,.72) ← village.css .vg-sheet-sub
        그림자 rgba(0,0,0,.45)        ← village.css:693 .vg-sheet box-shadow
        blur(8px)                    ← bgm-player.css:23 .bgm-chip
   ============================================================ */

/* ── 화면 = 씬 하나 ────────────────────────────────────────
   지도가 화면보다 커져도 페이지가 스크롤되면 안 된다. 마을 화면에는 이제
   흐름(flow) 안에 남는 요소가 없다 — 전부 fixed 로 떠 있다. */
html{ overflow:hidden; }
body.village-body{
  padding:0; gap:0; overflow:hidden;
  height:100vh; height:100dvh;
  /* 2026-09-02 (2차) — 카메라가 화면 아래 [광고가 덮는 띠]만큼은 원화로 안 채운다
     (village-fullbleed.js 아래가림()). 그 띠는 불투명한 네이티브 광고 뷰가 가리므로
     평소엔 안 보이지만, 광고가 **뜨기 직전 한 순간**(ads.js:114 가 실측 전 임시값 90 을
     먼저 넣는다)에는 잠깐 맨살이 드러난다. 그때 밝은 바탕이 번쩍이지 않게 밤색으로 깔아 둔다.
     값은 .vg-bleed 의 바탕색과 같은 것 하나다 — 새 색을 만들지 않았다. */
  background:#0d0a18;
  /* 하단 UI 가 피해야 하는 높이 = 네이티브 배너(ads.js 실측) + 안전영역.
     .village-toast(village.css:490)가 쓰는 --banner-ad-height 와 같은 값이다. */
  --vg-fb-bot: calc(var(--banner-ad-height,0px) + env(safe-area-inset-bottom,0px));
  --vg-fb-top: env(safe-area-inset-top,0px);
  --vg-fb-left: env(safe-area-inset-left,0px);
  --vg-fb-right: env(safe-area-inset-right,0px);
}
/* body.has-banner-ad 의 padding-bottom(style.css:124)은 흐름 요소용이라 여기선 의미가 없다.
   배너 회피는 위 --vg-fb-bot 로 각 UI 가 따로 한다. */
body.village-body.has-banner-ad{ padding-bottom:0; }

/* ── ① 지도 = 화면 전체 배경 ───────────────────────────────
   크기·자리는 village-fullbleed.js 가 인라인 px 로 덮어쓴다. 여기 값은
   스크립트가 돌기 전 첫 프레임용 기본값(폭만 맞는 상태)이다. */
.village-body .village-map{
  position:fixed; left:0; top:0;
  width:100vw; height:100dvh;
  max-width:none; min-height:0; margin:0; flex-shrink:0;
  aspect-ratio:auto;                 /* village.css:146 의 1024/1536 잠금 해제 — JS 가 px 로 준다 */
  border:none; border-radius:0;      /* 화면 끝에 테두리 선이 보이면 안 된다 */
  box-shadow:none;
  overflow:hidden;
  z-index:0;
}
/* ── ①-b 블리드 — 지도 상자가 창보다 작을 때 남는 띠 ──────────
   2026-08-31 폴더블 지시. 카메라가 [안전영역을 자르지 않는 배율]을 고르면
   넓적한 창(펼친 폴더블·태블릿)에서는 지도 좌우에 띠가 남는다. 그 자리를
   **같은 Master Map** 으로 채운다 — 새 이미지 asset 을 만들지 않는다(사람 지시 §4 / 추가요구 §1).
   village-fullbleed.js 블리드만들기() 가 index.html 의 .vg-art 세 장을 그대로 복제해 넣고,
   시간대(--dn)는 <html> 에 있어 저절로 따라온다(낮/밤이 지도와 어긋날 수 없다).
   흐리게+어둡게 깔아 [진짜 마을은 가운데 하나] 라는 것이 눈에 남게 한다. */
.vg-bleed{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  overflow:hidden; background:#0d0a18;
}
.vg-bleed .vg-bleed-in{
  position:absolute; inset:-6%;              /* blur 가장자리가 비지 않게 넉넉히 */
  filter:blur(26px) saturate(.72) brightness(.52);
  transform:scale(1.06);
}
/* 블리드가 없는 화면(접힌 폰처럼 지도가 창을 덮는 경우)에는 아예 그리지 않는다 —
   전면이 지도로 덮이므로 흐린 판을 계속 합성할 이유가 없다(저사양 기기 페인트 비용). */
body:not(.vg-has-bleed) .vg-bleed{ display:none; }
.village-map.vg-lite ~ .vg-bleed .vg-bleed-in,
body.vg-lite .vg-bleed .vg-bleed-in{ filter:none; background:#0d0a18; opacity:.35; }

/* 바텀시트가 열렸을 때만 지도를 UI 위로 올린다.
   지도는 position:fixed 라 그 자체가 스택 문맥이다 — 안에 있는 .vg-sheet(z29)는
   아무리 높아도 지도 밖 UI(z20)를 넘지 못한다. village-shop.js:108/139 가
   시트를 열고 닫을 때 지도에 붙였다 떼는 .vg-zoomed 를 그대로 신호로 쓴다
   (:has 는 보조 — village.css:761 과 같은 이중 안전망). */
.village-body .village-map.vg-zoomed,
.village-body .village-map:has(.vg-sheet.show){ z-index:80; }

/* 시트·막은 지도 상자(=원화 상자) 기준이라 가로화면에서 화면 밖으로 나간다.
   (900x600 실측: 지도 상자가 y -375~975 라 bottom:0 이 화면 아래 375px 지점이다)
   → 화면 기준으로 바꾼다. 지도에 transform 이 없으므로 fixed 의 기준은 뷰포트다. */
.village-body .vg-sheet-scrim{ position:fixed; }
.village-body .vg-sheet{
  position:fixed;
  /*  ★ 배너 광고 위로 (2026-08-22 실기기 SM-F966N 확인 — [상담하러 가기]·[닫기] 두 버튼이
      광고에 통째로 가려 눌리지 않았다. 광고는 별도 네이티브 뷰라 그 탭을 광고가 먹는다).
      바탕은 화면 끝까지 두고 **안쪽 여백만** 배너 높이만큼 준다 — 시트가 공중에 뜨면
      아래에 정체불명의 틈이 생긴다. `--vg-fb-bot` 은 이 파일 :42 의 [배너 + 안전영역] 이다. */
  padding-bottom:calc(18px + var(--vg-fb-bot));
  /*  시트 높이 상한 — 펼친 화면에서 대화가 길어져도 화면을 다 먹지 않는다.
      [창 높이 - 상단 UI - 배너] 안에서만 자라고 넘치면 안에서 스크롤한다. */
  max-height:calc(100dvh - 96px - var(--vg-fb-bot));
  overflow-y:auto; overscroll-behavior:contain;
}
/*  ── 폴더블 펼침·태블릿에서 시트가 지나치게 넓어지지 않게 (추가요구 §7) ──
    Compact(접힌 폰) : 거의 전체 폭 그대로 — 위 규칙이 그대로 산다.
    Medium 이상       : 가운데 정렬 + 상한. 분기점 600px 은 village-ui.css:328 이
    이미 쓰는 것과 같다(새 분기점을 만들지 않는다 — CLAUDE.md 규칙 6).
    ★ 대화 내용·버튼 구조는 손대지 않는다. 바뀌는 것은 width 와 max-height 뿐이다. */
@media (min-width:600px){
  .village-body .vg-sheet{
    left:50%; right:auto; transform:translate(-50%, 102%);
    width:min(560px, calc(100vw - 32px));
    border-radius:18px 18px 0 0;
  }
  .village-body .vg-sheet.show{ transform:translate(-50%, 0); }
}

/* 같은 이유로 [지도에 붙어 있던 UI 버튼]도 화면 기준으로 바꾼다.
   낮/밤 버튼: 은화 위젯(coins.js: fixed top:12 right:12, 높이 36 → 아래끝 48)
   바로 아래 56px 에 둔다. 개발자 은화 버튼은 그 아래 100px(56+32+12). */
.village-body .village-daynight{
  position:fixed;
  top:calc(56px + var(--vg-fb-top));
  right:calc(10px + var(--vg-fb-right));
}
.village-body .vg-devcoin{
  position:fixed;
  top:calc(100px + var(--vg-fb-top));
  right:calc(10px + var(--vg-fb-right));
}
/* 2026-09-14 — 복주머니·운명패스 개발자 버튼도 같은 이유로 화면 기준으로 바꾼다.
   village-ui.css 의 position:absolute 값은 [잘려서 안 보이는] 넓은 지도 기준이라
   실기기(fullbleed)에서는 아예 화면 밖으로 밀려 있었다(실측: x=755, 화면폭 749).
   은화 버튼(100px) 아래로 28px 씩 쌓는다 — village-ui.css 의 세로 간격과 같은 값. */
.village-body .vg-devpouch{
  position:fixed;
  top:calc(128px + var(--vg-fb-top));
  right:calc(10px + var(--vg-fb-right));
}
.village-body .vg-devpass{
  position:fixed;
  top:calc(156px + var(--vg-fb-top));
  right:calc(10px + var(--vg-fb-right));
}
.village-body .vg-devbar{
  position:fixed;
  top:calc(100px + var(--vg-fb-top));
  left:calc(8px + var(--vg-fb-left));
  right:calc(52px + var(--vg-fb-right));
}

/* ── ② 그림 위에 뜨는 UI ───────────────────────────────────*/

/* 뒤로가기 — 좌측 상단 고정.
   ★ 음악 칩과 겹치지 않게 하는 법: **칩을 아래로 내린다**(옆으로 밀지 않는다).
     bgm-player.css:55 는 흐름 안에 있는 .village-back 을 margin-left:52px 로 밀었는데,
     ① fixed 가 되면 그 여백은 자리 계산에 안 들어가고
     ② 칩은 44px 짜리 아이콘이 아니라 **곡 제목이 들어가는 알약**이다 —
        max-width:min(62vw,260px)(bgm-player.css:24), 제목만 150px(:29).
        2026-08-22 실측(412px 폭): 칩 폭 125px. 52px 옆으로 밀면 그대로 겹친다.
     그래서 bgm-player.css:51~56 이 정한 두 처방 중 **②번(칩이 60px 로 내려가 세로로 쌓인다)**
     을 쓴다 — 마을도 이제 [화면을 덮는 씬 + 좌상단 고정 뒤로가기]라 조건이 같다.
     60 = 44(뒤로가기 높이) + 8(간격) + 8(위 여백), bgm-player.css:57 과 같은 산술. */
body.village-body.bgm-chip-on .bgm-chip{ top:calc(60px + env(safe-area-inset-top,0px)); }
body.village-body.bgm-chip-on .village-back{ margin-left:0; }
.village-body .village-back{
  position:fixed; z-index:20;
  top:calc(8px + var(--vg-fb-top));
  left:calc(8px + var(--vg-fb-left));
  margin:0;
}
.village-body .village-back:not(.jelly){
  color:#fff; border-color:rgba(255,255,255,.45);
  background:rgba(20,15,40,.5);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  text-shadow:0 1px 6px rgba(0,0,0,.45);
}
.village-body .village-back:hover{ color:#fff; border-color:rgba(255,255,255,.75); }

/* 제목·설명 — 화면 위 가운데.
   세로(좁은) 화면의 세로 자리: 8(뒤로가기 위) + 44 + 8 = 60 이 칩 자리, 그 아래
   60 + 44 + 8 = 112 가 제목 자리다. 설명은 제목 아래 —
   제목 높이 실측 25px(2026-08-22, 412px 폭, font-size 1.12rem × line-height 1.4) + 여백 6 → 143.
   ★ width:max-content 로 [글자만큼만] 어두운 알약을 깔았다. 화면 전체를 덮는
     스크림 판을 깔면 그 판이 낮/밤 버튼·개발자 버튼(지도 스택 문맥 안, z0)을 덮어
     같이 어두워진다 — 그래서 판이 아니라 글자 뒤에만 깐다. */
.village-body .village-title,
.village-body > .sub{
  position:fixed; z-index:20;
  left:50%; transform:translateX(-50%);
  width:max-content; max-width:calc(100vw - 24px);
  margin:0; padding:4px 16px;
  border-radius:999px;
  color:#fff; text-align:center;
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  text-shadow:0 2px 10px rgba(0,0,0,.45);
}
.village-body .village-title{
  top:calc(112px + var(--vg-fb-top));
  background:rgba(20,15,40,.5);
}
.village-body > .sub{
  top:calc(143px + var(--vg-fb-top));
  background:rgba(20,15,40,.38);
  color:rgba(255,255,255,.72);
  opacity:1;                        /* village.css:130 의 opacity:.75 는 그림 위에서 흐리다 */
}

/* 넓은 화면(>=700px): 좌상단 뒤로가기·우상단 은화 옆으로 제목이 들어갈 자리가 남는다.
   village.css:134 가 이미 쓰는 것과 같은 분기점이다(새 분기점을 만들지 않는다).
   2026-08-22 실측(900px 폭): 뒤로가기 오른끝 129 · 은화 왼끝 742 → 가운데 613px 이 빈다. */
@media (min-width:700px){
  .village-body .village-title{ top:calc(8px + var(--vg-fb-top)); padding:6px 18px; }
  .village-body > .sub{ top:calc(52px + var(--vg-fb-top)); }
}

/* 아래 링크 줄 — 그림 위에 뜨는 알약 버튼.
   nav 높이(--vg-fb-nav)·설명글 높이(--vg-fb-foot)는 village-fullbleed.js 가 재서 넣는다.
   좁은 화면에서 3개가 두 줄로 접히기 때문에(412px 실측 96px = 44+8+44) 숫자를 박으면 어긋난다.
   ★ 좌하단 소리 위젯(.tarot-audio-widget, audio.js — 412px 실측 x12~55 · y865~901)과는
     겹치지 않는다: 알약 줄은 가운데 정렬이라 두 줄 다 x80 부터 시작한다(실측). */
.village-body .nav-links{
  position:fixed; z-index:20;
  left:calc(8px + var(--vg-fb-left)); right:calc(8px + var(--vg-fb-right));
  bottom:calc(var(--vg-fb-bot) + 10px);
  margin:0;
  display:flex; flex-wrap:wrap; justify-content:center; gap:8px 10px;
}
/*  ★ 젤리(전체계획 #46)가 입혀진 링크는 **그림이 배경을 맡는다** — 여기서 칠하면
    특이도(0-2-1 > 0-1-0)로 젤리 그림을 덮어 버린다. 그래서 :not(.jelly) 로 비켜 준다. */
.village-body .nav-links a:not(.jelly){
  color:#fff; border-color:rgba(255,255,255,.45);
  background:rgba(20,15,40,.5);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  text-shadow:0 1px 6px rgba(0,0,0,.45);
  /* 터치 하한 44px — .village-back(village.css:110)과 같은 처방 */
  min-height:44px; box-sizing:border-box; display:inline-flex; align-items:center;
}
.village-body .nav-links a:hover{ color:#fff; border-color:rgba(255,255,255,.75); }

/* 안내 문장 — 링크 줄 바로 위.
   ★ 가운데 정렬을 left:50% + translateX(-50%) 로 하지 않는다: 그렇게 하면 [쓸 수 있는 폭]이
     화면의 오른쪽 절반뿐이라(fixed 요소의 포함블록이 left 부터 시작한다) max-width 보다
     먼저 그 절반에 걸려 글이 세 줄로 접힌다 — 2026-08-22 실측(412px 폭: 206px, 69px 높이).
     left:0/right:0 + margin-inline:auto 는 화면 전체 폭 안에서 가운데로 놓는다. */
.village-body .village-footer{
  position:fixed; z-index:20;
  left:calc(8px + var(--vg-fb-left)); right:calc(8px + var(--vg-fb-right));
  margin-inline:auto; width:max-content;
  bottom:calc(var(--vg-fb-bot) + 10px + var(--vg-fb-nav,48px) + 6px);
  margin-top:0; padding:5px 14px; border-radius:14px;
  max-width:min(94vw, 380px);
  font-size:.68rem; line-height:1.35;
  color:rgba(255,255,255,.72);
  background:rgba(20,15,40,.38);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  text-shadow:0 1px 6px rgba(0,0,0,.45);
}

/* 토스트는 하단 UI 더미 위로 올린다(village.css:490 은 배너+28px 이라 링크 줄과 겹친다).
   10(링크 아래여백) + nav + 6 + 설명글 + 10 = 링크·설명글 더미 바로 위. */
.village-body .village-toast{
  bottom:calc(var(--vg-fb-bot) + 26px + var(--vg-fb-nav,48px) + var(--vg-fb-foot,40px));
  z-index:90;
}
