/* 곤충 숲 — 양방향 반응형. 세로 3:4 / 가로 4:3 두 벌 레이아웃.
   글을 못 읽는 4~6세가 쓰므로 터치 타깃은 최소 72px (DESIGN_METHOD §4). */
:root{
  --touch:76px;            /* 합격선 72px + 여유 */
  --sap:#e8a020; --leaf:#4f8f3a; --wood:#8a5a2b; --ink:#2c2118;
  --panel:rgba(255,252,244,.92);
  --bg-portrait:url("../assets/bg/bg_zone1_meadow.webp");
  --bg-land:url("../assets/bg/bg_zone1_meadow_land.webp");
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
/* hidden 속성은 언제나 이긴다. display를 지정한 요소에 hidden을 걸면
   조용히 무시돼 '숨겼는데 보이는' 상태가 된다 (2026-08-28 census가 잡음). */
[hidden]{display:none !important}
html,body{height:100%;overflow:hidden;background:#cfe6a8}
body{font:600 clamp(18px,4.5vw,34px)/1.1 system-ui,"Segoe UI",sans-serif;color:var(--ink);
  user-select:none;touch-action:manipulation;
  /*
   * **아래로 쓸어도 새로고침되지 않게.** 아이는 화면을 아무렇게나 쓸고,
   * 폰 브라우저는 그걸 '당겨서 새로고침'으로 받는다 —
   * 게임이 통째로 다시 뜨면 뭘 하다 말았는지 알 수 없다.
   * (전체화면은 manifest 와 src/ui/fullscreen.js 가 맡는다)
   */
  overscroll-behavior:none}

.screen{position:fixed;inset:0;display:grid;background-size:cover;background-position:center bottom;
  /* 빛깔 층 + 배경 그림. 섞이는 건 **배경뿐**이라 글자·버튼은 또렷하게 남는다 */
  background-image:linear-gradient(var(--lap-tint,transparent),var(--lap-tint,transparent)),
                   var(--bg-portrait);
  background-blend-mode:overlay,normal}

/*
 * 화면 배치 — **참고 게임(고양이 건즈)의 배치를 그대로 가져온다** (설계 §01).
 *
 *   위:    재화만 (수액·이슬·구역)
 *   가운데: 놀이판 — 나무와 곤충. 여기가 주인공이다
 *   오른쪽: 기능 아이콘 세로 한 줄 (놀이판 위에 뜬다)
 *   아래:   게이지 + **힘·빠르기·수확 버튼 셋이 가로로**
 *
 * 설계 원문이 "**하단** 버튼 3개"다. 한때 가로 화면에서 이 셋을 오른쪽 기둥에
 * 세로로 세웠는데, 태블릿에서 버튼 하나가 291×248px이 되어 화면의 3분의 1을 먹었고
 * 무엇보다 **설계와 달랐다.** 이제 세로·가로 모두 하단 가로로 둔다.
 *
 * 기능 아이콘도 한때 재화와 함께 상단에 있었다. 열 개가 두 줄로 흐르면서
 * "뭐가 뭔지 모르겠다"가 됐다(2026-08-29 실제 기기). 재화와 섞지 않는다.
 */
.screen{grid-template-rows:auto 1fr auto auto;grid-template-areas:"hud" "field" "gauge" "btns"}
.hud{grid-area:hud} .field{grid-area:field} .loggage{grid-area:gauge} .buttons{grid-area:btns}

/* 기능 아이콘 — 놀이판 오른쪽에 세로로 뜬다. 격자에 자리를 차지하지 않는다. */
/*
 * 기능 아이콘 — 놀이판 옆에 세로로 뜬다.
 *
 * **한 줄로는 모자란다.** 열 개가 다 열리면 832px가 필요한데 태블릿 가로는 660px라
 * 위아래로 잘려 나갔다(2026-08-29 실제 기기에서 확인).
 * 그래서 **넘치면 왼쪽으로 두 번째 줄**이 생기게 한다 — 참고 게임도 좌우 양쪽을 쓴다.
 */
/*
 * **버튼은 작게, 좌우 양쪽으로.**
 *
 * 참고 게임을 자로 재 보니 사이드 버튼이 **화면 폭의 12%**였다(1242px 화면에 150px).
 * 우리는 76px / 375px = **20%**였다 — 1.7배 크다. 그래서 놀이판을 잡아먹고,
 * 한쪽에만 몰려서 다 열리면 위아래로 길게 늘어섰다
 * (사장님: "메뉴도 좌우로 작게 좀 나와야 하는데 메뉴가 크니까", 2026-08-29).
 *
 * 이제 **왼쪽 줄과 오른쪽 줄**로 나눈다. 손가락이 닿는 최소 크기(--touch)는
 * 지키되, 큰 화면에서 더 커지지 않게 12%로 묶는다.
 */
.tools{position:absolute;top:0;bottom:0;z-index:2;   /* **놀이판 안**이라 HUD를 안 가린다 */
  display:flex;flex-direction:column;gap:6px;padding:6px;
  pointer-events:none;overflow:visible;justify-content:flex-start;
  align-content:flex-start}
.tools.right{right:0;align-items:flex-end}
.tools.left{left:0;align-items:flex-start}
@media (orientation:landscape){ .tools{justify-content:center} }
.tools .eggbtn{pointer-events:auto}

@media (orientation:landscape){
  .screen{background-image:linear-gradient(var(--lap-tint,transparent),var(--lap-tint,transparent)),
                          var(--bg-land)}
  /* 가로에서는 세로 공간이 귀하다 — 놀이판을 조금 양보하고 버튼은 그대로 하단에 둔다 */
  .buttons{padding:6px 10px}
  .btn{max-height:clamp(64px,13vh,96px)}
}

.hud{display:flex;gap:8px;padding:8px 10px;flex-wrap:wrap;align-content:flex-start}
.coin{display:flex;align-items:center;gap:6px;background:var(--panel);
  border:3px solid var(--wood);border-radius:999px;padding:4px 12px 4px 6px;
  box-shadow:0 3px 0 rgba(0,0,0,.18);min-width:0}
.coin-num{overflow:hidden;text-overflow:ellipsis}
/* 초당 수입 — 강화하면 여기가 오른다. 그게 "세졌다"이다 */
.coin-rate{font-size:.46em;color:#1f5c12;margin-left:2px;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.coin-icon{width:clamp(30px,6.5vmin,44px);height:clamp(30px,6.5vmin,44px);
  object-fit:contain;display:block;flex:none}
.fallback-sap{background:var(--sap);border-radius:50%;border:3px solid #a86a10}
.fallback-dew{background:#7fc7e8;border-radius:50%;border:3px solid #3f8fb5}
.zone{display:flex;align-items:center;justify-content:center;
  background:var(--panel);border:3px solid var(--leaf);border-radius:999px;
  padding:4px 12px;font-size:.8em;box-shadow:0 3px 0 rgba(0,0,0,.18);flex:none}
.zone::before{content:"🪵";margin-right:6px}
/* 스테이지 번호 — 구역-통나무. 참고 게임의 Stage 8-2 와 같은 자리다 */
.zone-dash{opacity:.5;margin:0 1px}
#stageNum{font-variant-numeric:tabular-nums}
.logneed{opacity:.55;font-size:.85em}

/*
 * 사이드 버튼 — 그림 하나로 무엇인지 말한다.
 *
 * **평평하면 게임 같지 않다**(사장님, 2026-08-29). 참고 게임 버튼은 셋을 갖췄다:
 *   ① 두꺼운 테두리   ② 안쪽 그라데이션   ③ **아래쪽 두툼한 단**
 * 누르면 그 단이 사라지며 실제로 내려앉는다 — 그 한 겹이 "눌리는 물건"을 만든다.
 */
.eggbtn{width:clamp(52px,12vmin,var(--touch));height:clamp(52px,12vmin,var(--touch));
  flex:none;padding:0;cursor:pointer;display:grid;place-items:center;position:relative;
  border:3px solid var(--wood);border-radius:22px;
  background:linear-gradient(180deg,#fff6dd 0%,var(--panel) 55%,#e6cf9e 100%);
  box-shadow:0 5px 0 #8a6236, 0 7px 6px rgba(0,0,0,.28),
             inset 0 2px 0 rgba(255,255,255,.75);
  transition:transform .07s, box-shadow .07s}
/* 눌리면 단만큼 내려앉는다 */
.eggbtn:active{transform:translateY(5px);
  box-shadow:0 0 0 #8a6236, 0 1px 3px rgba(0,0,0,.3),
             inset 0 2px 0 rgba(255,255,255,.6)}
.eggbtn img,.eggbtn-fallback{width:76%;height:76%;object-fit:contain;display:block;
  filter:drop-shadow(0 2px 2px rgba(0,0,0,.28))}
.eggbtn-fallback{background:#9ccf6a;border-radius:50% 50% 46% 46%/58% 58% 42% 42%}

/* 자동 강화 — 켜지면 초록으로 확실히 바뀐다. 글자 하나라 네 살도 자리로 기억한다 */
.autobtn .auto-mark{font-size:.62em;color:var(--wood);line-height:1}
.autobtn.on{border-color:var(--leaf);
  background:linear-gradient(180deg,#dff6c4 0%,#b6e58a 55%,#8fce5f 100%);
  box-shadow:0 5px 0 #4f8a2a, 0 7px 6px rgba(0,0,0,.28),
             inset 0 2px 0 rgba(255,255,255,.75)}
.autobtn.on .auto-mark{color:#1f5c12}
.autobtn.on:active{box-shadow:0 0 0 #4f8a2a, 0 1px 3px rgba(0,0,0,.3),
             inset 0 2px 0 rgba(255,255,255,.6)}
.eggbtn{position:relative}
.eggbtn .badge{position:absolute;top:-4px;right:-4px;min-width:26px;height:26px;
  display:grid;place-items:center;background:var(--leaf);color:#fff;
  border:2px solid #fff;border-radius:999px;font-size:.5em;padding:0 5px}
/*
 * **할 일이 있는 버튼만 빛난다.** 없으면 흐리다 — 네 살에게 "지금 여기"를 말해 준다.
 *
 * ⚠ 전에는 버튼 **id 를 하나씩 적어** 뒀다. 그래서 썩었다(2026-08-29):
 *   - `#hatchBtn` 은 없어졌는데 규칙은 남아 있었다
 *   - **`#petBtn` 과 `#friendsBtn` 은 아예 빠져 있었다** — 코드가 `.ready` 를
 *     붙여 주는데도 **영영 안 빛났다.** 화면은 멀쩡해 보여서 눈에 안 띈다
 *
 * 그래서 목록을 없앴다. **자동 강화만 빼고 전부**가 이 규칙을 받는다 —
 * 자동 강화는 켜짐/꺼짐을 스스로 보여주므로 흐려지면 안 된다.
 * 버튼을 새로 만들어도 저절로 따라온다.
 */
.eggbtn:not(.autobtn){animation:none;opacity:.6;filter:grayscale(.5)}
.eggbtn:not(.autobtn).ready{opacity:1;filter:none;animation:glow 1.15s ease-in-out infinite}

/* 구역이 바뀔 때 화면이 한 번 밝아진다 — 글 없이 "열렸다"를 알린다 */
.screen.zone-up{animation:zoneflash .9s ease-out}

/*
 * **바퀴 빛깔** — 구역 그림 5개를 돌려 쓰기 때문에, 한 바퀴 돌면 배경이
 * 처음과 똑같아진다. 그러면 137번째 통나무를 밀고 있어도 화면은 첫날과 같다.
 * 그래서 바퀴마다 하늘빛을 한 칸씩 옮긴다 — 같은 풀밭인데 아침 → 낮 → 노을 →
 * 자주 → 푸른밤. 배경 그림을 더 안 받고도 "멀리 왔다"가 보인다.
 * 다섯 바퀴에서 멈춘다(그 뒤로도 계속 바뀌면 색이 이상해진다).
 */
.screen[data-lap="1"]{--lap-tint:rgba(255,196,110,.30)}   /* 낮 — 따뜻하게 */
.screen[data-lap="2"]{--lap-tint:rgba(255,138,84,.34)}    /* 노을 */
.screen[data-lap="3"]{--lap-tint:rgba(168,116,224,.32)}   /* 자주 */
.screen[data-lap="4"]{--lap-tint:rgba(84,120,220,.34)}    /* 푸른밤 */
.screen[data-lap="5"]{--lap-tint:rgba(120,230,200,.30)}   /* 새벽 */
@keyframes zoneflash{0%{filter:brightness(2.1) saturate(1.4)}100%{filter:none}}
.coin-num{font-variant-numeric:tabular-nums;font-size:1.05em}

.field{position:relative;display:grid;place-items:center;min-height:0}
.tree{position:relative;border:0;background:none;padding:0;cursor:pointer;
  width:min(52vmin,340px);height:min(52vmin,340px);
  display:grid;place-items:center;transition:transform .07s}
.tree:active{transform:scale(.94)}
.tree img{width:100%;height:100%;object-fit:contain;pointer-events:none}
.tree-fallback{width:70%;height:80%;background:var(--wood);border:4px solid #5d3b1b;
  border-radius:26% 26% 12% 12%/32% 32% 8% 8%}

/*
 * ── 놀이판의 두 자리 ──────────────────────────────────────
 *
 * 사장님이 참고 게임과 대조해 정한 구조다(2026-08-29):
 * **장수풍뎅이·사슴벌레가 주인공**이고, 그들이 통나무를 민다.
 * 나머지 도감 곤충들은 **나무에서 수액을 모은다.**
 *
 *   나무 둘레 ── 일꾼(.bugs)  · 작게, 여럿      → 수액
 *   통나무 옆 ── 주인공(.heroes) · 크게, 둘     → 미는 속도
 *
 * 예전엔 26종을 다 통나무 옆에 세워서 누가 주인공인지도, 왜 세지는지도
 * 안 보였다. 참고 게임이 고양이를 둘셋만 내보내는 이유가 이것이다.
 */

/* ── 모으는 쪽 — 나무 밑동에 붙는다 ─────────────────────── */
.bugs{position:absolute;left:50%;top:56%;transform:translateX(-50%);
  display:flex;align-items:flex-end;justify-content:center;
  width:min(46vmin,300px);z-index:2;pointer-events:none}
/* 여럿이 되면 겹쳐 붙는다 — 나무를 둘러싼 무리로 보이게 */
.bug + .bug{margin-left:min(-1.5vmin,-9px)}
.bugs[data-n="1"] .bug,.bugs[data-n="2"] .bug{margin-left:min(1vmin,6px)}
.bug{display:block;object-fit:contain;animation:sip 2.4s ease-in-out infinite}
/* 수액을 빠는 몸짓 — 매달려 꿈틀거린다 */
@keyframes sip{
  0%,100%{transform:translateY(0) rotate(0)}
  50%{transform:translateY(-5%) rotate(-2deg)}}
.bug.small{width:min(9vmin,58px)}
.bug.mid{width:min(11vmin,74px)}
.bug.big{width:min(13vmin,88px)}
.bug:nth-child(2){animation-delay:.4s} .bug:nth-child(3){animation-delay:.8s}
.bug:nth-child(4){animation-delay:1.2s} .bug:nth-child(5){animation-delay:1.6s}
.bug-fallback{border-radius:44% 44% 40% 40%;border:3px solid rgba(0,0,0,.35)}

/* ── 미는 쪽 — 주인공과 통나무는 한 덩어리다 ─────────────
 * 떨어져 있으면 미는 것으로 안 보이고, 통나무만 움직이면 "혼자 굴러간다"가 된다
 * (사장님: "통나무를 밀 때 통나무와 곤충이 떨어져 있잖니").
 * --push 는 게이지 비율(0~1), --travel 은 forest.js 가 잰 남은 거리다. */
.pushgroup{position:absolute;bottom:5%;z-index:3;pointer-events:none;
  left:calc(3% + var(--push,0) * var(--travel,40%));
  display:flex;align-items:flex-end;gap:0;
  transition:left .12s linear}
.heroes{display:flex;align-items:flex-end;gap:min(1vmin,6px);margin-right:-3%}
.hero{display:block;object-fit:contain;
  width:min(20vmin,132px);height:min(20vmin,132px);
  animation:push-strain 1.1s ease-in-out infinite}
.hero:nth-child(2){animation-delay:.55s}
/* 미는 힘이 들어간 자세 — 앞으로 기울었다 돌아온다 */
@keyframes push-strain{
  0%,100%{transform:translateX(0) rotate(0)}
  50%{transform:translateX(5%) rotate(2.5deg)}}

/*
 * **걸음** — 같은 자리에 두 장을 겹쳐 놓고 번갈아 보여 준다.
 *
 * 한 장짜리를 CSS 로 흔들면 **사진이 흔들리는 것처럼** 보인다(사장님, 2026-08-29).
 * 다리가 실제로 바뀌어야 걷는 것으로 읽힌다.
 *
 * `steps(1)` 이라야 **탁 바뀐다.** 부드럽게 겹치면(fade) 다리가 넷으로 보인다 —
 * 두 장이 반쯤 함께 떠 있는 순간이 생기기 때문이다.
 */
.hero-walk{position:relative}
.hero-walk .hero-f1,.hero-walk .hero-f2{
  display:block;width:100%;height:100%;object-fit:contain}
.hero-walk .hero-f2{position:absolute;inset:0}
.hero-walk .hero-f1{animation:step-a .44s steps(1,end) infinite}
.hero-walk .hero-f2{animation:step-b .44s steps(1,end) infinite}
@keyframes step-a{0%,49.9%{opacity:1}50%,100%{opacity:0}}
@keyframes step-b{0%,49.9%{opacity:0}50%,100%{opacity:1}}
/* 걸음 장이 아직 안 온 종 — 한 장을 계속 보여 준다 */
.hero-walk.one-frame .hero-f1{animation:none;opacity:1}
.hero-fallback{border-radius:44% 44% 40% 40%;border:3px solid rgba(0,0,0,.35)}
/*
 * **아직 못 만난 주인공** — 회색 실루엣으로 자리를 지킨다.
 * 참고 게임의 미보유 실루엣과 같은 역할이다: 빈자리가 곧 목표가 된다.
 * 장수풍뎅이는 4구역에 가야 만나므로 한동안 이 자리가 비어 있다.
 */
.hero-ghost{width:min(20vmin,132px);height:min(16vmin,106px);
  background:rgba(30,34,28,.30);
  border:3px dashed rgba(255,255,255,.55);
  border-radius:46% 46% 40% 40%;
  animation:ghost-wait 2.4s ease-in-out infinite}
@keyframes ghost-wait{0%,100%{opacity:.42}50%{opacity:.72}}

/*
 * **자는 동안 모은 것** — 켤 때 한 번 뜨는 판.
 * 예전엔 숫자가 스치기만 해서 "밤새 이만큼 모았다"가 아이에게 안 남았다.
 */
.awaycard{position:fixed;inset:0;z-index:12;display:grid;place-items:center;
  background:rgba(20,26,16,.55);padding:20px}
.awaycard-box{display:grid;justify-items:center;gap:6px;max-width:min(84vw,380px);
  background:var(--panel);border:5px solid var(--wood);border-radius:26px;padding:16px 18px 18px;
  box-shadow:0 8px 0 #8a6236, 0 12px 20px rgba(0,0,0,.35);
  animation:awaycard-in .35s ease-out}
@keyframes awaycard-in{from{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}
.awaycard-title{font-size:.6em;text-align:center}
.awaycard-pic{width:min(34vw,150px);height:min(34vw,150px);object-fit:contain}
.awaycard-amount{display:flex;align-items:center;gap:8px;font-size:1.05em;color:#a86a10}
.awaycard-amount img{width:1.3em;height:1.3em;object-fit:contain}
.awaycard-go{min-height:var(--touch);min-width:60%;margin-top:4px;
  border:4px solid var(--wood);border-radius:999px;padding:6px 22px;font-size:.62em;cursor:pointer;
  background:linear-gradient(180deg,#dff6c4 0%,#b6e58a 55%,#8fce5f 100%);
  box-shadow:0 5px 0 #4f8a2a, 0 7px 6px rgba(0,0,0,.28)}
.awaycard-go:active{transform:translateY(5px);box-shadow:0 0 0 #4f8a2a}

/* 수액 방울 팝업 */
.pops{position:absolute;inset:0;pointer-events:none;overflow:hidden}
/* 숫자 — 참고 게임은 화면에 늘 20~35개가 떠 있다. 우리는 0~1개였다.
   값에 따라 세 단계로 갈라 크고 진하게 보여준다. */
.pop{position:absolute;display:flex;align-items:center;gap:4px;
  font-size:.62em;color:#8a4b00;text-shadow:0 2px 0 #fff,0 0 6px #fff;
  animation:rise .9s ease-out forwards;will-change:transform,opacity}
.pop img{width:22px;height:22px}
/* 큰 값 · 아주 큰 값 — 커지고 색이 진해진다 */
.pop.mid{font-size:.78em;color:#c06a00}
.pop.big{font-size:.95em;color:#e05500;text-shadow:0 2px 0 #fff,0 0 10px #ffd28a}
/* 탭으로 얻은 것 — 다른 색이라 "내가 눌러서 나온 것"이 티가 난다 */
.pop.tap{color:#2f7d20;font-size:.9em;text-shadow:0 2px 0 #fff,0 0 10px #bdf0a8}
/* 통나무를 밀어냈을 때처럼 크게 알릴 것 */
.pop.reward{font-size:1.05em;color:#1f6fa8;text-shadow:0 2px 0 #fff,0 0 12px #bfe6ff}
@keyframes rise{
  0%{opacity:0;transform:translate(0,0) scale(.8)}
  15%{opacity:1;transform:translate(0,-8px) scale(1.05)}
  100%{opacity:0;transform:translate(var(--dx,0),-84px) scale(1)}
}

/* 통나무 게이지 */
.loggage{display:flex;align-items:center;gap:8px;padding:0 10px 8px;flex:none}
.loggage-bar{flex:1;height:24px;background:rgba(255,255,255,.65);border:3px solid var(--wood);
  border-radius:999px;overflow:hidden}
.loggage-fill{height:100%;width:0;background:linear-gradient(90deg,#b3781f,var(--sap));
  border-radius:999px;transition:width .12s linear}
.loggage-count{min-width:2.4em;text-align:center;background:var(--panel);
  border:3px solid var(--wood);border-radius:14px;padding:2px 8px;font-size:.78em}

/*
 * 하단 강화 버튼 — **가운데 큰 숫자가 체감의 전부다.**
 *
 * 참고 게임 버튼에는 다섯이 들어 있다: 이름 · 레벨 · **지금 효과 값** · 값 · 게이지.
 * 우리는 **지금 효과 값 하나가 빠져 있었다.** 그래서 눌러도 레벨만 1 오르고
 * 무엇이 얼마나 좋아졌는지 안 보였다 — "강화를 해도 체감이 없다"(사장님).
 */
.buttons{display:flex;gap:6px;padding:0 6px calc(6px + env(safe-area-inset-bottom))}
.btn{flex:1 1 0;min-width:0;min-height:var(--touch);position:relative;overflow:hidden;
  display:grid;grid-template-columns:auto 1fr;grid-template-areas:"icon val" "icon price";
  align-items:center;gap:0 6px;
  border:3px solid var(--wood);border-radius:20px;padding:8px 10px 12px;
  background:linear-gradient(180deg,#fff6dd 0%,var(--panel) 55%,#e6cf9e 100%);
  box-shadow:0 5px 0 #8a6236, 0 7px 6px rgba(0,0,0,.28),
             inset 0 2px 0 rgba(255,255,255,.75);
  cursor:pointer;opacity:.62;filter:grayscale(.55);
  transition:transform .07s,box-shadow .07s,opacity .2s,filter .2s}
.btn img,.btn .icon-fallback{grid-area:icon;
  width:clamp(28px,7vmin,44px);height:clamp(28px,7vmin,44px);object-fit:contain;
  filter:drop-shadow(0 2px 2px rgba(0,0,0,.28))}
/* **지금 얼마나 세졌나** — 누를 때마다 이 숫자가 오른다 */
.btn-val{grid-area:val;justify-self:start;font-size:.62em;line-height:1;
  font-variant-numeric:tabular-nums;color:#3f2d14;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.btn .price{grid-area:price;justify-self:start;display:flex;align-items:center;gap:3px;
  font-size:.5em;font-variant-numeric:tabular-nums;opacity:.85}
.btn .price img{width:18px;height:18px}
.btn .lv{position:absolute;top:3px;right:6px;background:var(--leaf);color:#fff;
  border-radius:999px;padding:1px 7px;font-size:.42em;
  box-shadow:0 2px 0 rgba(0,0,0,.25)}
.btn.can{opacity:1;filter:none;border-color:var(--leaf);animation:can-ring 1.15s ease-in-out infinite}
/* 살 수 있을 때의 빛남 — box-shadow는 입체 단이 쓰고 있으므로 outline으로 낸다 */
@keyframes can-ring{0%,100%{outline:0 solid rgba(255,208,80,0)}
  50%{outline:5px solid rgba(255,208,80,.85);outline-offset:1px}}
.btn.can .btn-val{color:#1f5c12}
.btn:active{transform:translateY(5px);
  box-shadow:0 0 0 #8a6236, 0 1px 3px rgba(0,0,0,.3),
             inset 0 2px 0 rgba(255,255,255,.6)}
@keyframes glow{0%,100%{box-shadow:0 0 0 0 rgba(255,208,80,.9)}
  50%{box-shadow:0 0 22px 7px rgba(255,208,80,.95)}}
.icon-fallback{background:var(--leaf);border-radius:12px}

/* 아침 선물 — 눌러서 여는 상자. 숫자만 스치면 아이가 무슨 일인지 모른다. */
.giftbox{position:fixed;inset:0;z-index:12;display:grid;place-items:center;gap:12px;
  grid-auto-flow:row;background:rgba(24,18,10,.62);cursor:pointer;
  animation:eggUp .45s cubic-bezier(.2,1.3,.4,1)}
.giftbox-pic{width:min(46vmin,300px);height:min(46vmin,300px);object-fit:contain;
  animation:giftwiggle 1.6s ease-in-out infinite}
.giftbox-fallback{background:#e8a020;border-radius:18px;border:5px solid #7a5a1a}
.giftbox-amt{display:flex;align-items:center;gap:8px;background:var(--panel);
  border:4px solid var(--leaf);border-radius:999px;padding:8px 24px;font-size:.9em}
.giftbox-amt img{width:38px;height:38px}
.giftbox.opened .giftbox-pic{animation:giftopen .4s ease-out forwards}
.giftbox.opened .giftbox-amt{animation:rise .4s ease-out forwards}
@keyframes giftwiggle{
  0%,100%{transform:rotate(0) scale(1)}
  30%{transform:rotate(-5deg) scale(1.03)}
  60%{transform:rotate(5deg) scale(1.03)}}
@keyframes giftopen{to{transform:scale(1.5);opacity:0}}

/* 밤 구역(4) — 어두운 배경에 검은 사슴벌레가 묻힌다.
   실측(2026-08-28): 밤 배경 하단 밝기 61, 애사슴벌레 48. 그냥 두면 대비가 없다.
   밝기를 배경 위로 올리고(48×1.4=67 > 61) 둘레에 빛을 준다 —
   반딧불·달빛으로 읽히니 밤 테마와도 맞는다. */
.screen[data-zone="4"] .bug,
.screen[data-zone="4"] .bug-fallback{
  filter:brightness(1.4) saturate(1.1) drop-shadow(0 0 9px rgba(255,240,180,.95))}
/* 나무는 수액이 빛나 원본 밝기가 169다(배경 61) — 밝기를 더 올리면 밤이 아니게 된다.
   둘레 빛만 줘서 배경에서 떨어뜨린다. */
.screen[data-zone="4"] .tree img{
  filter:drop-shadow(0 0 14px rgba(255,224,140,.5))}

/* 판 번호 — 아이에게는 안 보일 만큼 작게, 어른이 확인할 수 있을 만큼만.
   배포 후 '옛 화면이 캐시된 건지 진짜 버그인지'를 가르는 유일한 표시다. */
.ver{position:fixed;left:6px;bottom:2px;z-index:99;pointer-events:none;
  font:500 10px/1 system-ui,sans-serif;color:rgba(44,33,24,.35)}

/* 처음 온 아이에게 "여기를 두드려요"를 알려준다.
   네 살은 화면을 읽지 않는다 — 나무가 스스로 흔들려서 손이 가게 만든다.
   한 번 두드리면 사라지고 다시는 안 나온다(잔소리가 되면 안 된다). */
.tree.first{animation:tree-hint 1.6s ease-in-out infinite}
@keyframes tree-hint{
  0%,70%,100%{transform:scale(1)}
  80%{transform:scale(1.06)}
  90%{transform:scale(.98)}
}
.hint{position:absolute;left:50%;transform:translateX(-50%);z-index:3;
  bottom:calc(50% + min(26vmin,150px));pointer-events:none;
  background:var(--panel);border:3px solid var(--leaf);border-radius:999px;
  padding:6px 18px;font-size:.5em;white-space:nowrap;
  animation:hint-bob 1.6s ease-in-out infinite}
@keyframes hint-bob{0%,100%{transform:translate(-50%,0)}50%{transform:translate(-50%,-6px)}}

/* ── 밀고 있는 통나무 ──────────────────────────────────────
   지금까지 통나무는 하단 게이지의 숫자로만 있었다. 밀 대상이 화면에 없으니
   "무엇을 향해 일하는지"도, 밀어냈을 때의 완결감도 없었다
   (사장님: "나무를 밀면서 스테이지가 완결되는 느낌"). */
.log{position:relative;pointer-events:none;
  width:min(30vmin,200px);height:min(30vmin,200px);
  display:grid;place-items:center;
  animation:log-shake 1.1s ease-in-out infinite}
.log>img:not(.pushwave){width:100%;height:100%;object-fit:contain;
  filter:drop-shadow(0 6px 10px rgba(0,0,0,.25))}

/*
 * **미는 힘의 파동** — 통나무 왼쪽에서 오른쪽으로 퍼진다.
 * `--wave`(0~1)는 게이지가 얼마나 찼는지다. forest.js 가 넣는다.
 * 0이면 아예 안 보이고, 찰수록 빨라지고 진해진다.
 */
.pushwave{position:absolute;left:-42%;top:50%;translate:0 -50%;
  width:80%;height:80%;object-fit:contain;pointer-events:none;
  mix-blend-mode:screen;opacity:0;
  animation:push-wave calc(1.6s - var(--wave,0) * 1s) linear infinite;
  animation-play-state:running}
/* 40% 아래에서는 아예 안 나온다 — forest.js 가 .waving 을 붙였다 뗀다 */
.log:not(.waving) .pushwave{animation:none;opacity:0}
@keyframes push-wave{
  0%{opacity:0;transform:translateX(-14%) scale(.72)}
  35%{opacity:calc(.35 + var(--wave,0) * .5)}
  100%{opacity:0;transform:translateX(46%) scale(1.15)}}
.log-fallback{width:80%;height:60%;background:var(--wood);
  border:4px solid #5d3b1b;border-radius:24px}

@keyframes log-shake{
  0%,100%{transform:translateX(0) rotate(0)}
  50%{transform:translateX(-3px) rotate(-1.2deg)}
}
/* 게이지가 거의 다 차면 더 크게 흔들린다 — 곧 굴러간다는 신호 */
/*
 * **보스 통나무** — 매 구역 다섯 번째. 게이지가 2.5배라 눈에도 달라야 한다.
 * 더 크고, 붉은 기가 돌고, 무겁게 흔들린다.
 */
.log.boss{width:min(38vmin,250px);height:min(38vmin,250px);
  animation-duration:1.6s}
.log.boss img{filter:drop-shadow(0 8px 14px rgba(0,0,0,.35))
              drop-shadow(0 0 16px rgba(255,90,60,.55)) saturate(1.15)}
.log.almost{animation-duration:.45s}
.log.almost img{filter:drop-shadow(0 6px 10px rgba(0,0,0,.25)) brightness(1.06)}

/* 밀어냈다 — 오른쪽으로 굴러 나가고 새 통나무가 왼쪽에서 들어온다 */
.log.rolling{animation:log-roll .6s ease-in forwards;translate:none;transition:none}
@keyframes log-roll{
  to{transform:translateX(140%) rotate(220deg);opacity:0}
}
.log.coming{animation:log-come .45s ease-out}
@keyframes log-come{
  from{transform:translateX(60%) rotate(-90deg);opacity:0}
  to{transform:translateX(0) rotate(0);opacity:1}
}

/* 버튼 안의 진행 게이지 — 다음 구매까지 얼마나 찼나 */
.btn-bar{position:absolute;left:6%;right:6%;bottom:5px;height:6px;
  background:rgba(0,0,0,.14);border-radius:999px;overflow:hidden}
.btn-bar i{display:block;height:100%;width:0;border-radius:999px;
  background:linear-gradient(90deg,#7cc24a,var(--leaf));transition:width .12s linear}
.btn.can .btn-bar i{background:linear-gradient(90deg,#ffd450,#ff9f1a)}

/* 구역 진행 — 화면 맨 위 얇은 띠 */
.zonebar{position:fixed;top:0;left:0;right:0;height:5px;z-index:5;
  background:rgba(0,0,0,.16);pointer-events:none}
.zonebar i{display:block;height:100%;width:0;
  background:linear-gradient(90deg,#7cc24a,#ffd450);transition:width .3s ease}

/* 새로 만났을 때 위에서 내려오는 알림 — 참고 게임의 "새로운 물고기!" 자리 */
/* 가운데 정렬을 **기본 상태에** 둔다. translate를 애니메이션 안에만 두면
   애니메이션이 끝난 뒤 제자리를 잃는다(첫 판이 화면 밖으로 나갔다). */
/*
 * 배너는 **HUD 아래**에 내려온다. 위에 겹치면 수액·이슬·스테이지가 가려진다
 * (사장님이 실제 기기에서 확인: "UI 겹쳐서 위 돈 안 보임", 2026-08-29).
 */
.getbanner{position:fixed;top:clamp(72px,13vh,120px);left:50%;transform:translateX(-50%);
  z-index:40;pointer-events:none;
  display:flex;align-items:center;gap:10px;
  background:var(--panel);border:4px solid var(--leaf);border-radius:999px;
  padding:6px 22px 6px 8px;box-shadow:0 6px 18px rgba(0,0,0,.25);
  animation:banner-in .35s ease-out, banner-out .4s ease-in 1.8s forwards}
.getbanner img{width:clamp(44px,9vmin,64px);height:clamp(44px,9vmin,64px);object-fit:contain}
.getbanner b{font-size:.6em;white-space:nowrap}
@keyframes banner-in{
  from{opacity:0;transform:translateX(-50%) translateY(-26px) scale(.9)}
  to{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}}
@keyframes banner-out{
  to{opacity:0;transform:translateX(-50%) translateY(-18px)}}

/* 나무 밑동의 빛 — 곤충이 일하고 있다는 표시.
   `screen` 합성으로 겹쳐야 참고 게임처럼 빛으로 보인다(그냥 얹으면 스티커가 된다).
   기본은 은은하게 두고, 초당 수액이 많아질수록 코드가 --lit 을 올린다. */
.glow{position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);
  width:min(78vmin,540px);height:min(78vmin,540px);object-fit:contain;
  pointer-events:none;z-index:0;mix-blend-mode:screen;
  opacity:calc(.18 + var(--lit,0) * .34);
  animation:glow-breathe 2.4s ease-in-out infinite}
@keyframes glow-breathe{0%,100%{transform:translate(-50%,-50%) scale(1)}
  50%{transform:translate(-50%,-50%) scale(1.06)}}

/* 통나무를 밀어냈다 — 색종이와 흙먼지가 터진다 (docs/JUICE_SPEC.md F).
   그전에는 게이지가 0으로 돌아갈 뿐이라 해낸 것이 티가 나지 않았다. */
.burst{position:absolute;pointer-events:none;z-index:3;
  width:min(60vmin,380px);height:min(60vmin,380px);
  left:50%;top:50%;transform:translate(-50%,-50%)}
.burst img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.burst .conf{animation:burst-conf 1.2s ease-out forwards}
.burst .dust{animation:burst-dust .8s ease-out forwards;mix-blend-mode:multiply;opacity:.6}
@keyframes burst-conf{
  0%{opacity:0;transform:scale(.35)}
  20%{opacity:1}
  100%{opacity:0;transform:scale(1.5) translateY(26px)}}
@keyframes burst-dust{
  0%{opacity:.6;transform:scale(.5)}
  100%{opacity:0;transform:scale(1.35)}}

/* 구역이 바뀌었다 */
/*
 * 구역이 갈리는 사이를 **덮는다**. 배경·수액나무·통나무가 한꺼번에 바뀌므로
 * 안 덮으면 그림이 뜨는 동안 화면이 깜빡인다 (docs/JUICE_SPEC.md J).
 * 곤충이 걸어가는 모습을 같이 보여 준다 — 네 살에게는 글자보다 그게 빠르다.
 */
.zonecall{position:fixed;inset:0;z-index:35;display:grid;place-content:center;
  justify-items:center;gap:6px;pointer-events:none;
  background:rgba(24,32,18,.55);backdrop-filter:blur(3px);
  animation:zonecall 1.4s ease-out forwards}
.zonecall b{font-size:1.5em;color:#fff;text-shadow:0 3px 0 #6a4a1e,0 0 24px #ffd450}
/* 걸어가는 곤충 — 왼쪽에서 들어와 오른쪽으로 지나간다 */
.zonecall-bug{width:min(28vmin,180px);height:min(28vmin,180px);object-fit:contain;
  filter:drop-shadow(0 6px 10px rgba(0,0,0,.45));
  animation:zonewalk 1.4s ease-in-out forwards}
@keyframes zonewalk{
  0%{transform:translateX(-90%) rotate(-4deg);opacity:0}
  25%{opacity:1}
  50%{transform:translateX(6%) rotate(3deg)}
  75%{transform:translateX(28%) rotate(-3deg)}
  100%{transform:translateX(70%) rotate(2deg);opacity:0}}
@keyframes zonecall{
  0%{opacity:0;transform:scale(.7)}
  20%{opacity:1;transform:scale(1)}
  75%{opacity:1}
  100%{opacity:0;transform:scale(1.1)}}

/* 수액 방울 캔버스 — 곤충과 나무 사이에 깔린다 */
.drops{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:2}

/* ── 겨루기 ────────────────────────────────────────────────
 * 5번째 통나무 자리에 **라이벌 곤충**이 선다 (docs/DESIGN_DUEL.md).
 * 통나무 그림을 곤충으로 갈아 끼우는 것뿐이라 자리·크기는 그대로 쓴다.
 */
.log.duel img{
  /* 마주 본다. 우리 곤충은 오른쪽을 보고 있으니 상대는 왼쪽을 봐야 한다 */
  transform:scaleX(-1);
  /* 통나무보다 작다 — 곤충이니까. 다만 라이벌이라 우리보다 조금 크다 */
  width:88%;height:88%}
/*
 * **사이를 띄운다.** 통나무는 곤충이 붙어서 미는 것이라 겹쳐도 되지만,
 * 겨루기는 **마주 보는 것**이라 붙어 있으면 누가 누군지 안 보인다.
 * ( 의 margin-right:-3% 를 되돌리고 더 띄운다)
 */
.pushgroup:has(.log.duel) .heroes{margin-right:min(4vmin,26px)}
/* 통나무처럼 통째로 흔들리지 않는다. **버티는 자세**로 밀린다 */
.log.duel{animation:duel-brace 1.1s ease-in-out infinite}
@keyframes duel-brace{
  0%,100%{transform:translateX(0)}
  50%{transform:translateX(2.5%)}}
.log.duel.almost{animation-duration:.5s}
/* 겨루는 중에는 파동을 끈다 — 상대를 미는 것이지 통나무를 미는 게 아니다 */
.log.duel .pushwave{display:none}

/*
 * **줄다리기 막대** — 가운데에서 시작해 오른쪽으로 밀어낸다.
 * `--tug` 는 0.5(가운데)에서 1(이김)까지. forest.js 가 넣는다.
 */
.loggage-fill.tug{
  width:100% !important;
  background:linear-gradient(90deg,
    var(--leaf) 0, var(--leaf) calc(var(--tug,.5) * 100%),
    rgba(0,0,0,.18) calc(var(--tug,.5) * 100%), rgba(0,0,0,.18) 100%)}
/* 가운데 표시 — 여기서 시작했다는 것이 보여야 한다 */
.loggage-fill.tug::after{
  content:"";position:absolute;left:50%;top:0;bottom:0;width:2px;
  background:rgba(255,255,255,.55)}
.loggage-fill{position:relative}

/*
 * **졌으면 물러난다** — 넘어졌다가 일어나 걸어 나간다.
 * 굴러가서 사라지는 통나무와 달라야 한다. 다치지도 없어지지도 않는다.
 */
.log.yielding{animation:duel-yield .9s ease-in forwards;translate:none;transition:none}
@keyframes duel-yield{
  0%   {transform:translateX(0) rotate(0);opacity:1}
  30%  {transform:translateX(6%) rotate(-24deg)}      /* 뒤로 넘어진다 */
  55%  {transform:translateX(10%) rotate(-8deg)}      /* 일어난다 */
  100% {transform:translateX(120%) rotate(0);opacity:0}  /* 걸어 나간다 */}
