/* 마리모 키우기 — 메인 스타일 */
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html, body {
  width: 100%; height: 100%;
  overflow: hidden;
  font-family: "Jua", "Noto Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  background: #1a2b22;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

#game {
  position: relative;
  width: 100%; height: 100%;
  max-width: 640px;
  margin: 0 auto;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* 무대(HUD·미터·장면·버튼바) 한 묶음. 좁은 화면에서는 #game 을 그대로 채운다. */
#stage-col {
  display: flex; flex-direction: column;
  width: 100%; height: 100%;
  min-height: 0;
}

/* ---------- HUD ---------- */
#hud {
  position: relative; z-index: 20;
  display: flex; flex-direction: column; gap: 6px;
  padding: 10px 14px 0;
}
.hud-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.hud-left { display: flex; flex-direction: column; gap: 6px; }
.gem-counter {
  display: flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.85);
  border-radius: 999px;
  padding: 4px 14px 4px 6px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  font-size: 18px; color: #1d6a5e; font-weight: bold;
  width: fit-content;
}
.gem-icon { width: 26px; height: 26px; object-fit: contain; }
.size-badge {
  background: rgba(255,255,255,0.85);
  border-radius: 999px;
  padding: 3px 14px;
  font-size: 13px; color: #3c5a4c;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  width: fit-content;
  display: flex; gap: 8px; align-items: baseline;
}
.size-badge b { color: #2e8b62; font-size: 15px; }
/* 밤에 화면이 어두워지는 게 오류로 보이지 않도록 시간을 함께 알려준다 */
.time-badge {
  background: rgba(255,255,255,0.85);
  border-radius: 999px;
  padding: 3px 12px;
  font-size: 12px; color: #55685d;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  width: fit-content;
  display: flex; gap: 5px; align-items: center;
  font-variant-numeric: tabular-nums;
}
.time-badge .time-label {
  font-family: "Noto Sans KR", sans-serif;
  font-size: 10.5px; color: #8aa094;
}
#game.night .time-badge {
  background: rgba(46,62,84,0.88);
  color: #dbe6f0;
}
#game.night .time-badge .time-label { color: #a9bdd4; }
.hud-right { display: flex; gap: 8px; margin-left: auto; flex: none; }
.chip-btn {
  border: none; cursor: pointer;
  background: rgba(255,255,255,0.85);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 14px; color: #3c5a4c;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  font-family: inherit;
}
.chip-btn:active { transform: scale(0.94); }
.chip-btn.off { opacity: 0.45; }

/* ---------- 케어 미터 ---------- */
#meters {
  position: relative; z-index: 20;
  display: flex; gap: 8px;
  padding: 10px 14px 8px;
}
.meter {
  flex: 1;
  background: rgba(255,255,255,0.8);
  border-radius: 12px;
  padding: 5px 10px 7px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
}
.meter-label { font-size: 11px; color: #55685d; display: block; margin-bottom: 3px; }
.meter-bar {
  height: 8px; border-radius: 99px;
  background: #e3ece5; overflow: hidden;
}
.meter-fill {
  height: 100%; width: 100%;
  border-radius: 99px;
  transition: width 0.6s ease, background 0.6s ease;
}
.fill-water { background: linear-gradient(90deg, #6fc3e8, #3f9fd8); }
.fill-nutrition { background: linear-gradient(90deg, #9fdc74, #5cb946); }
.fill-happiness { background: linear-gradient(90deg, #ffc46b, #ff9f43); }
.meter-fill.low { background: linear-gradient(90deg, #f2a0a0, #e05e5e) !important; }

/* ---------- 스와이프 뷰 컨테이너 ---------- */
#scene {
  position: relative; z-index: 10;
  flex: 1;
  min-height: 0;
}
#views {
  position: absolute; inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
#views::-webkit-scrollbar { display: none; }
.view {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  overflow: hidden;
}
#view-dots {
  position: absolute;
  bottom: 8px; left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 8px;
  z-index: 25;
}
.dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: rgba(255,255,255,0.45);
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
  transition: background 0.3s, transform 0.3s;
}
.dot.on { background: #fff; transform: scale(1.25); }
.view-hint {
  position: absolute;
  bottom: 24px; right: 12px;
  font-size: 12px;
  color: rgba(255,255,255,0.95);
  background: rgba(30,50,40,0.45);
  border-radius: 999px;
  padding: 4px 12px;
  z-index: 24;
  pointer-events: none;
  animation: hint-pulse 2.4s ease-in-out infinite;
}
.view-hint.right { right: auto; left: 12px; }
@keyframes hint-pulse { 0%,100% { opacity: 0.9; } 50% { opacity: 0.4; } }

/* ---------- 뷰 1: 방 전경 ---------- */
#room-bg {
  position: absolute; inset: 0;
  background: url("../assets/bg-window.webp") center 30% / cover no-repeat;
  transition: filter 2s ease;
}
#game.night #room-bg { filter: brightness(0.45) saturate(0.7) hue-rotate(-20deg); }
#game.sunny #room-bg { filter: brightness(1.12) saturate(1.1); }
/* 어항 종류마다 비율·크기가 다르므로 JS가 변수로 넘겨준다 */
#jar-wrap {
  position: absolute;
  left: 50%; bottom: 6%;
  transform: translateX(-50%);
  width: min(var(--jar-vw, 72vw), var(--jar-px, 380px), var(--jar-vh, 48vh));
  aspect-ratio: var(--jar-aspect, 0.9525);
}
#jar {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  z-index: 1;
  pointer-events: none;
}
#water-tint {
  position: absolute;
  left: var(--wt-l, 12%); right: var(--wt-r, 12%);
  top: var(--wt-t, 34%); bottom: var(--wt-b, 12%);
  border-radius: 45%;
  background: radial-gradient(ellipse at center, rgba(120,190,230,0.10), rgba(60,140,190,0.18));
  z-index: 2;
  pointer-events: none;
  transition: background 1.5s ease;
}
/* 방 뷰 어항 속 물도 같은 6단계로 */
#water-tint.w1 { background: radial-gradient(ellipse at center, rgba(140,180,180,0.12), rgba(90,150,175,0.20)); }
#water-tint.w2 { background: radial-gradient(ellipse at center, rgba(150,175,150,0.15), rgba(110,150,120,0.24)); }
#water-tint.w3 { background: radial-gradient(ellipse at center, rgba(158,170,120,0.18), rgba(120,140,90,0.27)); }
#water-tint.w4 { background: radial-gradient(ellipse at center, rgba(155,160,95,0.22), rgba(115,125,65,0.32)); }
#water-tint.w5 { background: radial-gradient(ellipse at center, rgba(150,148,78,0.27), rgba(108,110,52,0.38)); }
#water-tint.w6 { background: radial-gradient(ellipse at center, rgba(142,132,62,0.33), rgba(98,95,42,0.45)); }
#marimo-mini {
  position: absolute;
  left: 50%; top: var(--mm-top, 62%);
  width: 34%;
  transform: translate(-50%, -50%);
  z-index: 3;
  cursor: pointer;
  transition: width 1s ease;
}
#glass-shine {
  position: absolute; inset: 0;
  z-index: 6;
  pointer-events: none;
  background: linear-gradient(115deg, rgba(255,255,255,0.14) 8%, transparent 20%, transparent 75%, rgba(255,255,255,0.08) 92%);
  border-radius: 50%;
  opacity: 0.8;
}

/* ---------- 뷰 2: 어항 속 클로즈업 ---------- */
#tank {
  position: absolute; inset: 0;
  background: url("../assets/bg-tank-empty.webp") center bottom / cover no-repeat, #8fd3e3;
  transition: filter 2s ease;
  overflow: hidden;
}
#game.night #tank { filter: brightness(0.5) saturate(0.75) hue-rotate(-15deg); }
#game.sunny #tank { filter: brightness(1.1) saturate(1.12); }
/* 수질 6단계 — 조금씩 누렇고 탁해진다 */
#tank { transition: filter 2.5s ease; }
#tank.w1 { filter: sepia(0.10) saturate(1.05) brightness(0.99); }
#tank.w2 { filter: sepia(0.20) saturate(1.10) hue-rotate(6deg) brightness(0.98); }
#tank.w3 { filter: sepia(0.32) saturate(1.16) hue-rotate(10deg) brightness(0.96); }
#tank.w4 { filter: sepia(0.45) saturate(1.24) hue-rotate(15deg) brightness(0.93); }
#tank.w5 { filter: sepia(0.58) saturate(1.32) hue-rotate(20deg) brightness(0.89); }
#tank.w6 { filter: sepia(0.72) saturate(1.40) hue-rotate(24deg) brightness(0.84); }
#game.night #tank.w1 { filter: sepia(0.10) brightness(0.50); }
#game.night #tank.w2 { filter: sepia(0.20) hue-rotate(6deg) brightness(0.49); }
#game.night #tank.w3 { filter: sepia(0.32) hue-rotate(10deg) brightness(0.48); }
#game.night #tank.w4 { filter: sepia(0.45) hue-rotate(15deg) brightness(0.46); }
#game.night #tank.w5 { filter: sepia(0.58) hue-rotate(20deg) brightness(0.44); }
#game.night #tank.w6 { filter: sepia(0.72) hue-rotate(24deg) brightness(0.41); }
#tank-rays {
  position: absolute; inset: 0;
  background:
    linear-gradient(100deg, transparent 18%, rgba(255,255,240,0.28) 22%, transparent 30%,
      transparent 42%, rgba(255,255,240,0.2) 48%, transparent 56%,
      transparent 68%, rgba(255,255,240,0.24) 74%, transparent 82%);
  opacity: 0;
  transition: opacity 1.5s ease;
  pointer-events: none;
}
#game.sunny #tank-rays { opacity: 1; }
#tank-floor { display: none; }
#deco-layer { position: absolute; inset: 0; z-index: 2; overflow: hidden; }

/* 방 뷰 어항 속 미니 장식 — 어항 속 뷰와 소장품을 동기화 */
#deco-layer-mini {
  position: absolute;
  left: var(--dm-l, 16%); right: var(--dm-r, 16%);
  top: var(--dm-t, 38%); bottom: var(--dm-b, 15%);
  z-index: 2;
  overflow: hidden;
  pointer-events: none;
}
.deco-m {
  position: absolute;
  display: none;
  object-fit: contain;
  filter: drop-shadow(0 2px 3px rgba(40,70,80,0.28));
}
.deco-m.owned { display: block; }
.deco-m-fallback {
  position: absolute;
  display: none;
  font-size: min(7vw, 30px);
  line-height: 1;
  filter: drop-shadow(0 2px 3px rgba(40,70,80,0.28));
  pointer-events: none;
}
.deco-m-fallback.owned { display: block; }
#decom-pebbles { left: 4%; bottom: 0; width: 44%; }
#decom-waterplant { left: -2%; bottom: 6%; width: 30%; }
#decom-shell { right: 2%; bottom: 2%; width: 24%; }
#decom-castle { right: -4%; bottom: 8%; width: 34%; }
#decom-snail {
  right: 30%; bottom: 0; width: 20%;
  animation: snail-crawl-m 26s ease-in-out infinite;
}
@keyframes snail-crawl-m {
  0%   { transform: perspective(420px) translateX(0) rotateY(0deg); }
  8%   { transform: perspective(420px) translateX(-8%) rotateY(0deg); }
  44%  { transform: perspective(420px) translateX(-150%) rotateY(0deg); }
  50%  { transform: perspective(420px) translateX(-150%) rotateY(180deg); }
  54%  { transform: perspective(420px) translateX(-150%) rotateY(180deg); }
  92%  { transform: perspective(420px) translateX(0) rotateY(180deg); }
  98%  { transform: perspective(420px) translateX(0) rotateY(360deg); }
  100% { transform: perspective(420px) translateX(0) rotateY(360deg); }
}
/* 작은 어항에서는 헤엄치는 폭이 넓으면 마리모 뒤로 들어가 버린다.
   물 윗쪽에서 좁게 오가도록 줄였다. */
#decom-shrimp {
  left: 6%; bottom: 74%; width: 18%;
  animation: shrimp-swim-m 11s ease-in-out infinite;
}
/* 새우도 같은 문제가 있었다. 50% 에만 scaleX(-1) 이 걸려 있어
   25%~75% 내내 폭이 줄었다 늘었다 했다 (11초 주기 중 5.5초). */
@keyframes shrimp-swim-m {
  0%   { transform: perspective(400px) translate(0, 0) rotate(-4deg) rotateY(0deg); }
  25%  { transform: perspective(400px) translate(45%, -14%) rotate(5deg) rotateY(0deg); }
  42%  { transform: perspective(400px) translate(78%, 6%) rotate(-3deg) rotateY(0deg); }
  50%  { transform: perspective(400px) translate(78%, 6%) rotate(-3deg) rotateY(180deg); }
  75%  { transform: perspective(400px) translate(32%, -10%) rotate(4deg) rotateY(180deg); }
  92%  { transform: perspective(400px) translate(0, 0) rotate(-4deg) rotateY(180deg); }
  100% { transform: perspective(400px) translate(0, 0) rotate(-4deg) rotateY(360deg); }
}
.deco {
  position: absolute;
  display: none;
  object-fit: contain;
  filter: drop-shadow(0 4px 6px rgba(40,70,80,0.25));
}
.deco.owned { display: block; }
#deco-pebbles { left: 8%; bottom: 6%; width: 34%; }
#deco-waterplant { left: 2%; bottom: 10%; width: 26%; }
#deco-shell { right: 6%; bottom: 8%; width: 20%; }
#deco-castle { right: 2%; bottom: 12%; width: 28%; }
#deco-snail {
  right: 24%; bottom: 5%; width: 17%;
  animation: snail-crawl 26s ease-in-out infinite;
}
/* 달팽이는 바닥을 천천히 왕복하며 기어다닌다.
   방향 전환을 scaleX(-1) 로 하면 CSS 가 1 에서 -1 로 보간하면서
   폭이 0 을 지나간다. 종이가 서는 것처럼 보인다.
   rotateY 에 perspective 를 붙이면 가까운 쪽이 커지고 먼 쪽이 작아져
   실제로 몸을 돌리는 것으로 읽힌다.
   0->180->360 으로 한 방향으로만 돌린다. 되감으면 어색하다. */
@keyframes snail-crawl {
  0%   { transform: perspective(500px) translateX(0) rotateY(0deg); }
  8%   { transform: perspective(500px) translateX(-6vw) rotateY(0deg); }
  44%  { transform: perspective(500px) translateX(-46vw) rotateY(0deg); }
  50%  { transform: perspective(500px) translateX(-46vw) rotateY(180deg); }
  54%  { transform: perspective(500px) translateX(-46vw) rotateY(180deg); }
  92%  { transform: perspective(500px) translateX(0) rotateY(180deg); }
  98%  { transform: perspective(500px) translateX(0) rotateY(360deg); }
  100% { transform: perspective(500px) translateX(0) rotateY(360deg); }
}
/* 새우는 헤엄쳐 다니는 아이라 위쪽 물속에 둔다.
   아래에 두면 함께 키우는 마리모와 자리가 겹쳐 뒤에 가려지고,
   말풍선도 마리모가 말하는 것처럼 보인다. */
#deco-shrimp {
  left: 8%; bottom: 62%; width: 18%;
  animation: shrimp-swim 9s ease-in-out infinite;
}
@keyframes shrimp-swim {
  0%, 100% { transform: translate(0, 0) rotate(-4deg); }
  25% { transform: translate(28px, -22px) rotate(4deg); }
  50% { transform: translate(6px, -40px) rotate(-3deg); }
  75% { transform: translate(-16px, -14px) rotate(5deg); }
}
/* 송사리 — 위치와 회전을 JS 가 매 프레임 정한다.
   달팽이·새우처럼 CSS 키프레임으로 하면 진행 방향과 회전이 따로 놀고,
   마리모에게 다가가 씻겨주는 동작도 못 넣는다.
   left/top 은 JS 가 %로 넣는다. transform 도 JS 가 통째로 쓴다. */
.deco.fish, .deco-m.fish {
  width: 15%;
  transform-origin: 50% 50%;
  will-change: transform, left, top;
}
.deco-m.fish { width: 17%; }

/* 이미지가 아직 없을 때 이모지 대체 */
.deco-fallback {
  position: absolute;
  display: none;
  text-align: center;
  filter: drop-shadow(0 4px 6px rgba(40,70,80,0.25));
  pointer-events: none;
}
.deco-fallback.owned { display: block; }

#marimo {
  position: absolute;
  left: 50%; top: 56%;
  width: 46%;
  transform: translate(-50%, -50%);
  z-index: 3;
  cursor: pointer;
  transition: width 1s ease;
  will-change: transform;
}
@keyframes idle-bob {
  0%, 100% { transform: translate(-50%, -50%) rotate(0deg); }
  50% { transform: translate(-50%, -53%) rotate(2deg); }
}

/* ===== 행동 상태 (실제 마리모 습성) =====
   광합성 산소 기포로 떠오르고, 빛이 없으면 가라앉는다.
   생체시계 영향으로 아침에 잘 뜨고, 광합성이 막히면 바닥에서 움직이지 않는다. */

/* 평상시: 중층에서 잔잔히 흔들림 */
#marimo.b-idle, #marimo-mini.b-idle, .cos-wrap.b-idle {
  animation: b-idle 5s ease-in-out infinite;
}
@keyframes b-idle {
  0%, 100% { transform: translate(-50%, -50%) rotate(0deg); }
  50% { transform: translate(-50%, -54%) rotate(2.5deg); }
}

/* 햇빛(활발한 광합성): 산소 기포로 수면까지 떠오름 */
#marimo.b-floating, #marimo-mini.b-floating, .cos-wrap.b-floating {
  animation: b-floating 7s ease-in-out infinite;
}
@keyframes b-floating {
  0%   { transform: translate(-50%, -50%) rotate(-2deg); }
  35%  { transform: translate(-52%, -78%) rotate(3deg); }
  65%  { transform: translate(-48%, -84%) rotate(-3deg); }
  100% { transform: translate(-50%, -50%) rotate(-2deg); }
}

/* 아침(생체시계): 중층까지 살랑살랑 떠오름 */
#marimo.b-drifting, #marimo-mini.b-drifting, .cos-wrap.b-drifting {
  animation: b-drifting 9s ease-in-out infinite;
}
@keyframes b-drifting {
  0%, 100% { transform: translate(-50%, -50%) rotate(0deg); }
  30% { transform: translate(-54%, -64%) rotate(4deg); }
  70% { transform: translate(-46%, -60%) rotate(-4deg); }
}

/* 기분 최고: 통통 튀며 논다 */
#marimo.b-bouncy, #marimo-mini.b-bouncy, .cos-wrap.b-bouncy {
  animation: b-bouncy 1.9s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}
@keyframes b-bouncy {
  0%, 100% { transform: translate(-50%, -50%) scale(1, 1) rotate(0deg); }
  15% { transform: translate(-50%, -46%) scale(1.08, 0.9) rotate(-3deg); }
  40% { transform: translate(-50%, -68%) scale(0.94, 1.09) rotate(4deg); }
  60% { transform: translate(-50%, -58%) scale(1, 1) rotate(-2deg); }
  80% { transform: translate(-50%, -47%) scale(1.06, 0.93) rotate(2deg); }
}

/* 밤: 산소가 빠져 바닥으로 내려가 쉼 */
#marimo.b-resting, #marimo-mini.b-resting, .cos-wrap.b-resting {
  animation: b-resting 8s ease-in-out infinite;
}
@keyframes b-resting {
  0%, 100% { transform: translate(-50%, -34%) rotate(-1.5deg); }
  50% { transform: translate(-50%, -36%) rotate(1.5deg); }
}

/* 광합성 억제(수질 악화·쇠약): 바닥에서 거의 움직이지 않음 */
#marimo.b-sunken, #marimo-mini.b-sunken, .cos-wrap.b-sunken {
  animation: b-sunken 11s ease-in-out infinite;
}
@keyframes b-sunken {
  0%, 100% { transform: translate(-50%, -30%) rotate(-4deg); }
  50% { transform: translate(-50%, -31%) rotate(-2deg); }
}
#marimo.wobble, #marimo-mini.wobble, .cos-wrap.wobble {
  animation: wobble 0.5s ease !important;
}
@keyframes wobble {
  0% { transform: translate(-50%, -50%) rotate(0) scale(1); }
  30% { transform: translate(-50%, -50%) rotate(-8deg) scale(1.06, 0.94); }
  60% { transform: translate(-50%, -50%) rotate(6deg) scale(0.95, 1.05); }
  100% { transform: translate(-50%, -50%) rotate(0) scale(1); }
}
#bubble-layer {
  position: absolute;
  left: 6%; right: 6%; top: 6%; bottom: 12%;
  overflow: hidden;
  z-index: 5;
  pointer-events: none;
}
#effect-layer {
  position: absolute; inset: 0;
  z-index: 6;
  pointer-events: none;
}

/* 기포 */
.bubble {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, rgba(255,255,255,0.95), rgba(190,230,255,0.45) 45%, rgba(150,210,250,0.18) 100%);
  border: 1px solid rgba(255,255,255,0.55);
  pointer-events: auto;
  cursor: pointer;
  animation: bubble-rise linear forwards;
}
@keyframes bubble-rise {
  from { transform: translateY(0) scale(0.6); opacity: 0.6; }
  30% { opacity: 1; }
  to { transform: translateY(var(--rise, -120px)) scale(1.05); opacity: 0.85; }
}

/* 파티클 */
.particle {
  position: absolute;
  pointer-events: none;
  animation: particle-float 1.2s ease-out forwards;
  z-index: 8;
}
@keyframes particle-float {
  0% { transform: translate(-50%, -50%) scale(0.4); opacity: 0; }
  20% { opacity: 1; transform: translate(-50%, -70%) scale(1); }
  100% { transform: translate(-50%, -180%) scale(0.9) rotate(12deg); opacity: 0; }
}
.particle img { width: 100%; height: 100%; object-fit: contain; }

/* 행동으로 자란 양 표시 */
.grow-pop {
  position: absolute;
  left: 50%; top: 26%;
  transform: translateX(-50%);
  font-family: "Jua", sans-serif;
  font-size: 15px;
  color: #2e8b62;
  text-shadow: 0 2px 6px rgba(255,255,255,0.95), 0 0 3px rgba(255,255,255,0.9);
  pointer-events: none;
  z-index: 9;
  animation: grow-pop 2s ease-out forwards;
}
@keyframes grow-pop {
  0% { opacity: 0; transform: translateX(-50%) translateY(8px) scale(0.8); }
  15% { opacity: 1; transform: translateX(-50%) translateY(-2px) scale(1.06); }
  75% { opacity: 1; transform: translateX(-50%) translateY(-24px) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-38px) scale(1); }
}

/* 떨어지는 영양제 방울 */
.nutrient-drop {
  position: absolute;
  width: 18px; height: 24px;
  background: radial-gradient(circle at 35% 30%, #d9ffa8, #7ede3e 60%, #4cae23);
  border-radius: 50% 50% 55% 55% / 40% 40% 62% 62%;
  z-index: 7;
  animation: drop-fall 0.8s ease-in forwards;
  pointer-events: none;
}
@keyframes drop-fall {
  from { transform: translateY(-40px) scale(0.8); opacity: 0.9; }
  to { transform: translateY(140px) scale(1); opacity: 0; }
}
#dropper-anim {
  position: absolute;
  width: 22%;
  top: 2%; left: 42%;
  z-index: 7;
  pointer-events: none;
  animation: dropper-in 1.6s ease forwards;
}
@keyframes dropper-in {
  0% { transform: translateY(-60px) rotate(-10deg); opacity: 0; }
  25% { transform: translateY(0) rotate(0); opacity: 1; }
  75% { transform: translateY(0) rotate(0); opacity: 1; }
  100% { transform: translateY(-40px); opacity: 0; }
}

/* 물갈이 연출 */
.washing #water-tint {
  background: radial-gradient(ellipse at center, rgba(160,220,255,0.35), rgba(90,180,235,0.4)) !important;
}
#tank.washing { filter: brightness(1.15) saturate(1.1); }

/* ---------- 말풍선 ---------- */
#speech {
  position: absolute;
  top: 6%;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(255,255,255,0.95);
  border-radius: 18px;
  padding: 10px 18px;
  font-size: 16px;
  color: #3c5a4c;
  box-shadow: 0 4px 14px rgba(0,0,0,0.15);
  z-index: 26;
  /* 긴 말은 줄바꿈해서 화면 밖으로 나가지 않게. 한글은 단어 중간에서 끊지 않는다. */
  max-width: 84%;
  text-align: center;
  word-break: keep-all;
  transition: opacity 0.3s ease, transform 0.3s ease;
}
#speech::after {
  content: "";
  position: absolute;
  bottom: -8px; left: 50%;
  transform: translateX(-50%);
  border: 9px solid transparent;
  border-top-color: rgba(255,255,255,0.95);
  border-bottom: none;
}
#speech.hidden { opacity: 0; transform: translateX(-50%) translateY(6px); pointer-events: none; }

/* ---------- 캐릭터 대화 말풍선 ---------- */
.talk-bubble {
  position: absolute;
  z-index: 22;
  --bubble: rgba(255,255,255,0.96);
  background: var(--bubble);
  border-radius: 16px;
  padding: 7px 14px;
  font-family: "Noto Sans KR", sans-serif;
  font-size: 13px;
  color: #3c5a4c;
  max-width: 56%;
  box-shadow: 0 3px 12px rgba(0,0,0,0.16);
  pointer-events: none;
  animation: talk-in 0.28s ease;
  line-height: 1.4;
}
.talk-bubble::after {
  content: "";
  position: absolute;
  bottom: -7px; left: var(--tail, 22px);
  border: 8px solid transparent;
  border-top-color: var(--bubble);
  border-bottom: none;
}
.talk-bubble.right::after { left: auto; right: 22px; }
/* 말하는 쪽 아래에 놓였을 때는 꼬리도 위를 가리켜야 한다 */
.talk-bubble.below::after {
  bottom: auto; top: -7px;
  border-top: none;
  border-bottom: 8px solid var(--bubble);
}
@keyframes talk-in {
  from { opacity: 0; transform: translateY(6px) scale(0.94); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
/* 자리는 JS 가 말하는 쪽 위로 잡아준다 (placeTalk). 색만 구분한다. */
#talk-s { --bubble: rgba(255,247,235,0.96); }
#talk-p { --bubble: rgba(255,238,238,0.96); }

/* ---------- 액션 버튼 ---------- */
#actions {
  position: relative; z-index: 20;
  display: flex; justify-content: center; gap: 10px;
  padding: 10px 12px calc(14px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, transparent, rgba(20,35,28,0.25));
}
.action-btn {
  border: none; cursor: pointer;
  width: 80px; height: 84px;
  border-radius: 22px;
  background: rgba(255,255,255,0.92);
  box-shadow: 0 4px 14px rgba(0,0,0,0.18);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  font-family: inherit;
  font-size: 12px; color: #3c5a4c;
  transition: transform 0.12s ease;
}
.action-btn:active { transform: scale(0.92); }
.action-btn img { width: 40px; height: 40px; object-fit: contain; }
.action-btn .btn-emoji { font-size: 34px; line-height: 40px; }
.action-btn.active { background: #ffe9b8; box-shadow: 0 0 0 3px #ffc46b, 0 4px 14px rgba(0,0,0,0.18); }
.action-btn:disabled { opacity: 0.5; }

/* ---------- 모달 ---------- */
.modal {
  position: absolute; inset: 0;
  z-index: 50;
  background: rgba(20, 35, 28, 0.55);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.modal.hidden { display: none; }
.modal-card {
  background: #fdfdf8;
  border-radius: 22px;
  padding: 26px 24px 22px;
  max-width: 340px;
  width: 100%;
  max-height: 86%;
  overflow-y: auto;
  text-align: center;
  box-shadow: 0 12px 40px rgba(0,0,0,0.3);
}
.modal-card h2 { color: #2e8b62; font-size: 22px; margin-bottom: 10px; font-weight: normal; }
.modal-card p { color: #55685d; font-size: 15px; line-height: 1.6; margin-bottom: 16px; }
.daily-gem {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 26px; color: #1d8a76; font-weight: bold;
  margin-bottom: 18px;
}
.daily-gem img { width: 40px; height: 40px; object-fit: contain; }
.primary-btn {
  border: none; cursor: pointer;
  background: linear-gradient(135deg, #5cbf83, #3da368);
  color: #fff;
  font-family: inherit;
  font-size: 17px;
  border-radius: 999px;
  padding: 12px 36px;
  box-shadow: 0 4px 12px rgba(61, 163, 104, 0.4);
}
.primary-btn:active { transform: scale(0.95); }
.primary-btn.danger {
  background: linear-gradient(135deg, #ef8080, #d95a5a);
  box-shadow: 0 4px 12px rgba(217, 90, 90, 0.4);
}

/* ---------- 상점 ---------- */
/* 상점은 항목이 많아 스크롤되므로, 목록만 스크롤하고 닫기 버튼은 항상 보이게 한다 */
.shop-card {
  text-align: left;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.shop-card h2, .shop-sub { text-align: center; flex-shrink: 0; }
.shop-card #shop-tabs { flex-shrink: 0; }
.shop-card #shop-items {
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
  padding-right: 2px;
}
.shop-card .primary-btn { flex-shrink: 0; margin-top: 4px; }
.shop-sub { font-size: 13px !important; margin-bottom: 12px !important; }
#shop-items { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.shop-item {
  display: flex; align-items: center; gap: 12px;
  background: #f1f6ef;
  border-radius: 16px;
  padding: 10px 12px;
}
.shop-item .thumb {
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  font-size: 34px;
  flex-shrink: 0;
}
.shop-item .thumb img { width: 100%; height: 100%; object-fit: contain; }
.shop-item .info { flex: 1; min-width: 0; }
.shop-item .info .iname { font-size: 15px; color: #2c4a3a; }
.shop-item .info .idesc { font-size: 11.5px; color: #7b8d80; font-family: "Noto Sans KR", sans-serif; line-height: 1.4; }
.buy-btn {
  border: none; cursor: pointer;
  font-family: inherit;
  background: linear-gradient(135deg, #57b7d8, #3a92c4);
  color: #fff;
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 13px;
  display: flex; align-items: center; gap: 4px;
  flex-shrink: 0;
  box-shadow: 0 3px 8px rgba(58,146,196,0.35);
}
.buy-btn img { width: 16px; height: 16px; object-fit: contain; }
.buy-btn:disabled { background: #c3cfc6; box-shadow: none; }
.buy-btn.owned-label { background: #8dc79f; box-shadow: none; }
.shop-card .primary-btn { display: block; margin: 0 auto; }

/* ---------- 성장 배너 ---------- */
#levelup {
  position: absolute;
  top: 30%; left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  display: flex; align-items: center; gap: 10px;
  background: rgba(255,255,255,0.95);
  border-radius: 999px;
  padding: 12px 26px;
  box-shadow: 0 8px 30px rgba(0,0,0,0.25);
  font-size: 19px; color: #b8860b;
  animation: levelup-pop 3s ease forwards;
  white-space: nowrap;
}
#levelup img { width: 34px; height: 34px; object-fit: contain; }
#levelup.hidden { display: none; }
@keyframes levelup-pop {
  0% { transform: translateX(-50%) scale(0.5); opacity: 0; }
  15% { transform: translateX(-50%) scale(1.08); opacity: 1; }
  25% { transform: translateX(-50%) scale(1); }
  80% { opacity: 1; }
  100% { opacity: 0; }
}

/* ---------- 오늘의 미션 패널 ---------- */
#quest-panel {
  position: absolute;
  top: 10px; right: 0;
  z-index: 30;
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 6px;
  max-width: 82%;
}
#quest-toggle {
  border: none; cursor: pointer;
  font-family: inherit; font-size: 13px; color: #3c5a4c;
  background: rgba(255,255,255,0.92);
  border-radius: 999px 0 0 999px;
  padding: 7px 14px 7px 14px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.18);
  display: flex; align-items: center; gap: 6px;
  position: relative;
}
#quest-toggle .q-icon { font-size: 15px; }
#quest-badge {
  background: #ff6b6b; color: #fff;
  border-radius: 50%;
  width: 17px; height: 17px;
  font-size: 11px; line-height: 17px; text-align: center;
  font-weight: bold;
  animation: badge-pop 1.4s ease-in-out infinite;
}
@keyframes badge-pop { 0%,100% { transform: scale(1); } 50% { transform: scale(1.18); } }
#quest-list {
  display: flex; flex-direction: column; gap: 6px;
  padding-right: 10px;
}
#quest-list.collapsed { display: none; }
.quest {
  background: rgba(255,255,255,0.94);
  border-radius: 14px;
  padding: 8px 12px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.16);
  min-width: 190px;
  display: flex; flex-direction: column; gap: 4px;
}
.quest.done { background: rgba(226,246,232,0.96); }
.quest .qtop { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.quest .qtext {
  font-family: "Noto Sans KR", sans-serif;
  font-size: 11.5px; color: #3c5a4c; line-height: 1.35;
}
.quest .qreward {
  display: flex; align-items: center; gap: 3px;
  font-size: 12px; color: #1d8a76; font-weight: bold;
  white-space: nowrap;
}
.quest .qreward img { width: 14px; height: 14px; object-fit: contain; }
.quest .qbar {
  height: 6px; border-radius: 99px;
  background: #e3ece5; overflow: hidden;
}
.quest .qfill {
  height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, #7fd3a4, #4bae7a);
  transition: width 0.4s ease;
}
.quest .qclaim {
  border: none; cursor: pointer;
  font-family: inherit; font-size: 11.5px;
  background: linear-gradient(135deg, #ffc46b, #f0a13a);
  color: #5a3a06;
  border-radius: 999px;
  padding: 4px 12px;
  white-space: nowrap;
  animation: badge-pop 1.4s ease-in-out infinite;
}
.quest .qcheck { font-size: 13px; color: #4bae7a; white-space: nowrap; }

/* 안내가 떠 있는 동안은 스와이프 힌트를 감춘다. 자리가 겹치고,
   한 번에 두 가지를 시키면 둘 다 안 읽힌다. */
#game.tipping .view-hint { opacity: 0; }
.view-hint { transition: opacity 0.25s ease; }

/* ---------- 하단 팁 ---------- */
#tip {
  position: absolute;
  bottom: 118px; left: 50%;
  transform: translateX(-50%);
  z-index: 28;
  background: rgba(30,50,40,0.82);
  color: #fff;
  font-family: "Noto Sans KR", sans-serif;
  font-size: 13px;
  border-radius: 999px;
  padding: 8px 18px;
  white-space: nowrap;
  pointer-events: none;
  animation: tip-in 0.4s ease;
}
@keyframes tip-in {
  from { opacity: 0; transform: translateX(-50%) translateY(8px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* ---------- 미니게임 ---------- */
/* 미니게임 배경. 본편 어항과 같은 렌더 그림을 쓴다.
   단색 그러데이션이면 옆에 붙은 마리모 그림과 화풍이 어긋난다.
   (bg-underwater 는 만들어두고 안 쓰던 그림이라 용량도 늘지 않는다) */
#minigame {
  position: absolute; inset: 0;
  z-index: 60;
  background:
    /* 아래쪽 모래가 밝아서 흰 기포가 묻힌다. 물빛을 옅게 덮어 대비를 살린다. */
    linear-gradient(180deg, rgba(255,255,255,0.20), rgba(255,255,255,0) 30%,
                    rgba(90,180,205,0) 58%, rgba(70,160,190,0.42) 100%),
    url("../assets/bg-underwater.webp") center bottom / cover no-repeat,
    linear-gradient(180deg, #a5e4f0 0%, #7cc9e0 45%, #55a8cc 100%);
  overflow: hidden;
}
#mg-field { position: absolute; inset: 0; }
#mg-hud {
  position: absolute;
  top: 12px; left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 10px;
  z-index: 3;
}
.mg-stat {
  background: rgba(255,255,255,0.9);
  border-radius: 14px;
  padding: 4px 9px;
  font-size: 10px; color: #55685d;
  display: flex; flex-direction: column; align-items: center;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  min-width: 48px;
  white-space: nowrap;
}
#mg-hud { gap: 6px; }
#mg-hud .mg-stat b { font-size: 17px; }
.mg-stat b {
  font-family: "Jua", sans-serif;
  font-size: 19px; color: #2e8b62;
  font-variant-numeric: tabular-nums;
}
.mg-stat.combo b { color: #e08a1e; }
.mg-stat.combo.hot b { color: #e0431e; }
#mg-countdown {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: "Jua", sans-serif;
  font-size: 72px; color: #fff;
  text-shadow: 0 4px 18px rgba(0,60,90,0.5);
  z-index: 5;
  pointer-events: none;
}
.mg-panel {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 6;
  background: #fdfdf8;
  border-radius: 22px;
  padding: 24px 26px 20px;
  width: min(88%, 330px);
  text-align: center;
  box-shadow: 0 12px 40px rgba(0,0,0,0.3);
}
.mg-panel h2 {
  font-family: "Jua", sans-serif; font-weight: normal;
  color: #2e8b62; font-size: 22px; margin-bottom: 10px;
}
.mg-panel p {
  font-family: "Noto Sans KR", sans-serif;
  color: #55685d; font-size: 13.5px; line-height: 1.6;
  margin-bottom: 14px; white-space: pre-line;
}
.mg-panel .mg-best { font-size: 12.5px; color: #7b8d80; margin-bottom: 14px; }
.mg-panel .mg-best b { color: #e08a1e; }
.mg-final {
  font-family: "Jua", sans-serif;
  font-size: 17px; color: #3c5a4c; margin-bottom: 10px;
}
.mg-final b { font-size: 30px; color: #2e8b62; }
.ghost-btn {
  border: none; cursor: pointer;
  background: transparent;
  color: #7b8d80;
  font-family: inherit; font-size: 14px;
  padding: 10px 20px 2px;
  display: block; margin: 0 auto;
}
.primary-btn + .ghost-btn { margin-top: 4px; }

/* 미니게임 기포 */
.mg-bubble {
  position: absolute;
  border-radius: 50%;
  cursor: pointer;
  background: radial-gradient(circle at 32% 28%, rgba(255,255,255,0.98), rgba(200,238,255,0.5) 45%, rgba(150,210,250,0.22) 100%);
  border: 1.5px solid rgba(255,255,255,0.7);
  box-shadow: inset -4px -6px 10px rgba(120,190,225,0.35);
  will-change: transform;
}
.mg-bubble { display: flex; align-items: center; justify-content: center; font-size: 20px; }
/* 작은 기포 — 빠르고 점수 높음 */
.mg-bubble.k-tiny {
  background: radial-gradient(circle at 32% 28%, rgba(255,255,255,0.98), rgba(190,255,225,0.6) 45%, rgba(120,230,190,0.3) 100%);
  border-color: rgba(200,255,235,0.85);
}
/* 큰 기포 — 느리지만 놓치면 콤보가 끊긴다 */
.mg-bubble.k-giant {
  background: radial-gradient(circle at 34% 26%, rgba(255,255,255,0.9), rgba(200,225,255,0.45) 50%, rgba(150,190,245,0.22) 100%);
  border-width: 2px;
}
/* 얼음 기포 — 두 번 눌러야 깨진다 */
.mg-bubble.k-ice {
  background: radial-gradient(circle at 32% 28%, #ffffff, #cfefff 45%, #a5d8f5 100%);
  border-color: #eaf8ff;
  box-shadow: 0 0 12px rgba(150,220,255,0.7), inset -4px -6px 10px rgba(120,180,220,0.4);
}
.mg-bubble.k-ice.cracked {
  background: radial-gradient(circle at 32% 28%, #ffffff, #e8f7ff 45%, #bfe6fa 100%);
  box-shadow: 0 0 16px rgba(180,235,255,0.9), inset -3px -4px 8px rgba(120,180,220,0.3);
  transform-origin: center;
  filter: brightness(1.1);
}
/* 무지개 기포 — 화면의 기포를 한꺼번에 터뜨린다 */
.mg-bubble.k-rainbow {
  background: conic-gradient(from 0deg, #ffb3ba, #ffdfba, #ffffba, #baffc9, #bae1ff, #d5baff, #ffb3ba);
  border-color: #fff;
  box-shadow: 0 0 18px rgba(255,255,255,0.9);
  animation: rb-spin 2.4s linear infinite;
}
/* 가운데 반짝임. ✨ 이모지를 쓰다가 게임 안 그림으로 바꿨다 —
   이모지는 기기마다 모양이 달라지고 옆의 렌더 그림과 어긋난다. */
.mg-bubble.k-rainbow::after {
  content: "";
  position: absolute; inset: 18%;
  background: url("../assets/ui-sparkle.webp") center / contain no-repeat;
  filter: drop-shadow(0 0 3px rgba(255,255,255,0.9));
}
@keyframes rb-spin { to { filter: hue-rotate(360deg); } }

.mg-bubble.gold, .mg-bubble.k-gold {
  background: radial-gradient(circle at 32% 28%, #fffdf0, #ffdf7a 45%, #f0b429 100%);
  border-color: #fff3c4;
  box-shadow: 0 0 16px rgba(255,200,60,0.7), inset -4px -6px 10px rgba(200,140,20,0.35);
}
/* 성게 — 피해야 할 것. 기포가 아니라 생물이라 기포 껍데기를 지우고
   그림만 남긴다. 폭탄 이모지를 쓰다가 바꿨다. */
.mg-bubble.k-bomb {
  background: url("../assets/pop-urchin.webp") center / contain no-repeat !important;
  border: none !important;
  box-shadow: none !important;
  filter: drop-shadow(0 3px 6px rgba(20,50,70,0.35));
  animation: urchin-drift 3.2s ease-in-out infinite;
}
@keyframes urchin-drift {
  0%, 100% { rotate: -7deg; }
  50%      { rotate: 7deg; }
}
.mg-bubble.bomb, .mg-bubble.k-bomb-old {
  background: radial-gradient(circle at 32% 28%, #ffeaea, #ff9b9b 45%, #e05555 100%);
  border-color: #ffd0d0;
  box-shadow: 0 0 14px rgba(224,85,85,0.55), inset -4px -6px 10px rgba(160,40,40,0.35);
}
.mg-pop {
  position: absolute;
  font-family: "Jua", sans-serif;
  font-size: 20px;
  color: #fff;
  text-shadow: 0 2px 8px rgba(0,60,90,0.6);
  pointer-events: none;
  animation: mg-pop-up 0.7s ease-out forwards;
  z-index: 4;
}
.mg-pop.gold { color: #ffe27a; font-size: 24px; }
.mg-pop.bad { color: #ff9b9b; }
@keyframes mg-pop-up {
  0% { transform: translate(-50%, -50%) scale(0.6); opacity: 0; }
  25% { transform: translate(-50%, -90%) scale(1.15); opacity: 1; }
  100% { transform: translate(-50%, -170%) scale(1); opacity: 0; }
}

/* ---------- 10분 진행 표시 ---------- */
#play-timer {
  position: absolute;
  /* 스와이프 안내(.view-hint)가 어항 바닥선 기준 bottom 24px, 높이 26px 로
     앉는다. 그 위로 완전히 비켜서게 108 + 58 = 166px 을 준다. */
  right: 12px; bottom: 168px;
  z-index: 27;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  pointer-events: none;
}
.pt-ring {
  width: 46px; height: 46px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  box-shadow: 0 2px 10px rgba(0,0,0,0.18);
  display: flex; align-items: center; justify-content: center;
  font-family: "Jua", sans-serif;
  font-size: 13px; color: #3da368;
  font-variant-numeric: tabular-nums;
}
.pt-label {
  font-family: "Noto Sans KR", sans-serif;
  /* v2.7: 9.5px 는 작은 화면에서 읽기 어렵다는 검수 지적. 키우고 바탕을 진하게. */
  font-size: 11px; color: #fff;
  background: rgba(30,50,40,0.68);
  border-radius: 999px; padding: 2px 8px;
  white-space: nowrap;
}
#play-timer.ready .pt-ring {
  background: linear-gradient(135deg, #ffd97a, #f0a13a);
  color: #5a3a06;
  animation: badge-pop 1.1s ease-in-out infinite;
}

/* ---------- 랜덤 카드 ---------- */
/* 앞뒤가 한 장의 카드로 보이도록 3D 뒤집기로 만든다.
   흔들림(bob)과 뒤집기(flip)는 같은 transform 속성을 쓰므로
   서로 덮어쓰지 않게 바깥/안쪽 요소로 나눠 걸었다. */
.card-stage {
  position: relative;
  height: 198px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 14px;
  perspective: 900px;
}
.card-bob { animation: card-bob 2.6s ease-in-out infinite; }
@keyframes card-bob {
  0%, 100% { transform: rotate(-2deg) translateY(0); }
  50%      { transform: rotate(2deg) translateY(-6px); }
}
.card-flip {
  position: relative;
  width: 130px; height: 182px;
  transform-style: preserve-3d;
  transition: transform 0.52s cubic-bezier(0.45, 0.05, 0.3, 1);
}
.card-flip.flip { transform: rotateY(180deg); }
.card-back, .card-front {
  position: absolute; inset: 0;
  border-radius: 14px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  box-shadow: 0 10px 24px rgba(14, 60, 52, 0.30);
}

/* 뒷면 - 물속. 어항 물빛에서 색을 가져왔다. */
.card-back {
  overflow: hidden;
  background:
    radial-gradient(circle at 22% 18%, rgba(255,255,255,0.30), rgba(255,255,255,0) 46%),
    radial-gradient(circle at 78% 88%, rgba(0, 40, 60, 0.34), rgba(0,0,0,0) 55%),
    linear-gradient(160deg, #3fa9a0 0%, #1f7f8c 46%, #14566d 100%);
  border: 4px solid #f3fbf6;
  display: flex; align-items: center; justify-content: center;
}
/* 잔물결 - 옅은 사선 결. 무늬가 없으면 색면으로 보인다. */
.card-back::before {
  content: ""; position: absolute; inset: 0;
  background-image: repeating-linear-gradient(
    -32deg, rgba(255,255,255,0.10) 0 2px, rgba(255,255,255,0) 2px 13px);
  opacity: 0.7;
}
.cb-mark { position: relative; width: 104px; height: 104px; }
.cb-ring {
  fill: none; stroke: rgba(255,255,255,0.30);
  stroke-width: 1.4; stroke-dasharray: 3 7;
}
.cb-fuzz { fill: rgba(215,248,224,0.60); }
.cb-ball { fill: rgba(215,248,224,0.60); }
.cb-moss { fill: rgba(28,110,110,0.30); }
.cb-gloss { fill: rgba(255,255,255,0.42); }
.cb-bub  { fill: rgba(255,255,255,0.45); }
/* 빛이 한 번씩 지나간다 - 아직 안 연 카드라는 신호 */
.cb-sheen {
  position: absolute; top: -60%; left: -70%;
  width: 55%; height: 220%;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.42) 50%, rgba(255,255,255,0) 100%);
  transform: rotate(18deg);
  animation: card-sheen 3.4s ease-in-out infinite;
}
@keyframes card-sheen {
  0%, 62%  { left: -70%; }
  92%, 100% { left: 125%; }
}

/* 앞면 - 뒤집혀 있다가 돌아온다 */
.card-front {
  transform: rotateY(180deg);
  background: linear-gradient(170deg, #ffffff 0%, #eef8f1 100%);
  border: 4px solid #cfe9d9;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px;
  padding: 8px 7px;
}
.card-front img { width: 92px; height: 92px; object-fit: contain; }
#card-name {
  font-family: "Jua", sans-serif; font-size: 16px; color: #2e8b62;
  text-align: center; line-height: 1.15;
}
.card-tag {
  font-size: 11px; color: #7b8d80;
  background: #eef3ef; border-radius: 999px;
  padding: 3px 10px;
  text-align: center; line-height: 1.25;
  max-width: 100%;
}
.card-tag.is-new {
  background: linear-gradient(135deg, #ffd97a, #f0a13a);
  color: #5a3a06; font-weight: bold;
}
/* 뒤집기가 끝나면 흔들림을 멈춘다. 받은 카드가 계속 흔들리면 산만하다. */
.card-bob.settled { animation: none; }

/* 세로가 짧은 화면(가로로 눕힌 폰 등)에서 열기 버튼이 밀려나지 않게 */
@media (max-height: 700px) {
  .card-stage { height: 166px; margin-bottom: 10px; }
  .card-flip { width: 112px; height: 156px; }
  .cb-mark { width: 88px; height: 88px; }
  .card-front img { width: 76px; height: 76px; }
  #card-name { font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .card-bob, .cb-sheen { animation: none; }
  .card-flip { transition-duration: 0.01s; }
  .card-flip.flip, .card-stage.charge .card-flip, .card-bob.settled .card-front::after { animation: none; }
  .card-glow, .card-rays, .card-flash, .card-spark, .card-confetti { display: none; }
}

/* ---------- 카드 뒤집기 연출 (v2.3) ----------
   달아오르기(charge) → 터짐(burst) → 안착(settled). 희귀도 클래스가 빛의 색을 정한다. */
.card-stage {
  overflow: hidden; border-radius: 16px;
  --ray: rgba(255, 220, 110, 0.55); --glow: rgba(255, 214, 90, 0.80);
}
.card-stage.r-dup  { --ray: rgba(120, 220, 205, 0.50); --glow: rgba(90, 200, 185, 0.70); }
.card-stage.r-rare { --ray: rgba(255, 180, 50, 0.80);  --glow: rgba(255, 160, 30, 1.0); }
.card-stage.r-gem  { --ray: rgba(140, 230, 190, 0.55); --glow: rgba(100, 210, 160, 0.80); }
.card-bob { position: relative; z-index: 2; }
.card-glow {
  position: absolute; left: 50%; top: 50%; width: 240px; height: 240px; margin: -120px 0 0 -120px;
  border-radius: 50%; pointer-events: none; opacity: 0; transform: scale(0.5);
  background: radial-gradient(circle, var(--glow) 0%, rgba(255,255,255,0) 65%);
}
.card-stage.charge .card-glow { animation: card-glow-charge 0.48s ease-in forwards; }
.card-stage.burst  .card-glow { animation: card-glow-burst 1s ease-out forwards; }
@keyframes card-glow-charge { to { opacity: 0.95; transform: scale(1.15); } }
@keyframes card-glow-burst  { 0% { opacity: 1; transform: scale(1.4); } 100% { opacity: 0.6; transform: scale(1.05); } }
.card-rays {
  position: absolute; left: 50%; top: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px;
  border-radius: 50%; pointer-events: none; opacity: 0; z-index: 1;
  background: repeating-conic-gradient(from 0deg, var(--ray) 0deg 9deg, rgba(255,255,255,0) 9deg 24deg);
  -webkit-mask: radial-gradient(circle, #000 0%, rgba(0,0,0,0.6) 35%, rgba(0,0,0,0) 62%);
          mask: radial-gradient(circle, #000 0%, rgba(0,0,0,0.6) 35%, rgba(0,0,0,0) 62%);
}
.card-stage.burst .card-rays { animation: card-rays-in 0.5s ease-out forwards, card-rays-spin 9s linear infinite; }
@keyframes card-rays-in   { from { opacity: 0; } to { opacity: 1; } }
@keyframes card-rays-spin { to { transform: rotate(360deg); } }
.card-flash {
  position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, #fff 0%, rgba(255,255,255,0.75) 30%, rgba(255,255,255,0) 70%);
}
.card-stage.burst .card-flash { animation: card-flash 0.45s ease-out forwards; }
@keyframes card-flash { 0% { opacity: 0; } 15% { opacity: 1; } 100% { opacity: 0; } }
/* 달아오르기: 흔들림이 점점 커진다 */
.card-stage.charge .card-bob { animation: none; }
.card-stage.charge .card-flip { animation: card-rattle 0.48s ease-in forwards; }
@keyframes card-rattle {
  0%   { transform: rotate(0) scale(1); }
  15%  { transform: rotate(-3deg) scale(1.01); }
  30%  { transform: rotate(3deg) scale(1.02); }
  45%  { transform: rotate(-5deg) scale(1.03); }
  60%  { transform: rotate(5deg) scale(1.05); }
  75%  { transform: rotate(-7deg) scale(1.06); }
  90%  { transform: rotate(7deg) scale(1.08); }
  100% { transform: rotate(0) scale(1.1); }
}
/* 뒤집기: 옆면을 지날 때 커졌다가 앞면에서 살짝 넘치고 돌아온다 */
.card-flip.flip { animation: card-flip-pop 0.7s cubic-bezier(0.22, 0.9, 0.3, 1.12) forwards; }
@keyframes card-flip-pop {
  0%   { transform: rotateY(0) scale(1.1); }
  45%  { transform: rotateY(90deg) scale(1.2); }
  100% { transform: rotateY(180deg) scale(1); }
}
/* 앞면 홀로그램 빛 — 안착한 뒤 계속 돈다 */
.card-front::after {
  content: ""; position: absolute; inset: 0; border-radius: 10px; pointer-events: none; opacity: 0;
  background: linear-gradient(115deg, rgba(255,255,255,0) 35%, rgba(255,255,255,0.7) 47%,
              rgba(255,230,160,0.6) 52%, rgba(255,255,255,0) 64%);
  background-size: 250% 250%;
}
.card-bob.settled .card-front::after { opacity: 1; animation: card-holo 2.4s ease-in-out infinite; }
@keyframes card-holo { 0% { background-position: 120% 0; } 100% { background-position: -20% 0; } }
.card-stage.r-new .card-front, .card-stage.r-rare .card-front {
  border-color: #ffd36b;
  box-shadow: 0 10px 24px rgba(14, 60, 52, 0.30), 0 0 26px var(--glow);
}
/* 불꽃과 색종이 (JS 가 만들고 지운다) */
.card-spark {
  position: absolute; left: 50%; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px;
  border-radius: 50%; pointer-events: none; z-index: 4; opacity: 0;
  background: radial-gradient(circle, #fff 0%, #ffe38a 45%, rgba(255,227,138,0) 72%);
  box-shadow: 0 0 8px #ffe38a;
  animation: card-spark 0.9s cubic-bezier(0.1, 0.8, 0.3, 1) var(--d, 0s) forwards;
}
@keyframes card-spark {
  0%   { opacity: 1; transform: translate(0, 0) scale(0.4); }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1.3); }
}
.card-confetti {
  position: absolute; top: -14px; left: var(--x); width: 8px; height: 12px; border-radius: 2px;
  background: var(--c); pointer-events: none; z-index: 4; opacity: 0;
  animation: card-confetti var(--dur, 1.5s) cubic-bezier(0.3, 0.6, 0.6, 1) var(--d, 0s) forwards;
}
@keyframes card-confetti {
  0%   { opacity: 1; transform: translateY(0) rotate(0); }
  100% { opacity: 0.15; transform: translateY(240px) rotate(var(--rot, 540deg)); }
}

/* ---------- 미니게임 선택 ---------- */
.game-pick {
  display: flex; align-items: center; gap: 12px;
  background: #f1f6ef;
  border-radius: 16px;
  padding: 12px 14px;
  margin-bottom: 10px;
  cursor: pointer;
  text-align: left;
  transition: transform 0.12s ease, background 0.2s ease;
}
.game-pick:active { transform: scale(0.97); }
.game-pick:hover { background: #e6f1e9; }
.gp-icon { font-size: 32px; flex-shrink: 0; }
.gp-info { flex: 1; min-width: 0; }
.gp-name { font-family: "Jua", sans-serif; font-size: 16px; color: #2c4a3a; }
.gp-desc {
  font-family: "Noto Sans KR", sans-serif;
  font-size: 11.5px; color: #7b8d80; line-height: 1.4;
}
.gp-best {
  font-size: 11px; color: #8aa094;
  white-space: nowrap; flex-shrink: 0;
}
.gp-best b { color: #e08a1e; font-size: 14px; font-family: "Jua", sans-serif; }

/* ---------- 상점 탭 ---------- */
#shop-tabs {
  display: flex; gap: 5px;
  margin-bottom: 12px;
}
.shop-tab {
  flex: 1;
  border: none; cursor: pointer;
  font-family: inherit; font-size: 12px;
  color: #7b8d80;
  background: #eef3ef;
  border-radius: 999px;
  padding: 7px 4px;
}
.shop-tab.on {
  background: linear-gradient(135deg, #5cbf83, #3da368);
  color: #fff;
}

/* ---------- 코스튬 레이어 ---------- */
/* 코스튬 래퍼는 마리모와 "같은 크기의 상자"여야 한다.
   애니메이션의 translate(%)가 각 요소 자신의 크기 기준이라,
   크기가 다르면 이동 거리가 달라져 코스튬이 따로 논다. */
.cos-wrap {
  position: absolute;
  left: 50%;
  top: 56%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  z-index: 4;
  pointer-events: none;
}
.cos-wrap img {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  object-fit: contain;
  filter: drop-shadow(0 2px 4px rgba(40,70,80,0.25));
}

/* ---------- 미니게임 2: 마리모 굴리기 ---------- */
#rollgame {
  position: absolute; inset: 0;
  z-index: 60;
  background: #6fb3cc;
  overflow: hidden;
}
#rg-canvas {
  position: absolute;
  left: 0; right: 0;
  top: 62px; bottom: 0;
  width: 100%;
  height: calc(100% - 62px);
  touch-action: none;
  display: block;
}
#rg-hud {
  position: absolute;
  top: 12px; left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 10px;
  z-index: 3;
}
#rg-hint {
  position: absolute;
  bottom: 18px; left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  background: rgba(20,45,55,0.55);
  color: #fff;
  font-family: "Noto Sans KR", sans-serif;
  font-size: 12.5px;
  border-radius: 999px;
  padding: 6px 16px;
  pointer-events: none;
  animation: hint-pulse 2.4s ease-in-out infinite;
}
.rg-quit {
  position: absolute;
  top: 12px; right: 12px;
  z-index: 4;
  border: none; cursor: pointer;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  color: #55685d;
  font-size: 16px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.18);
}
.rg-score {
  font-family: "Jua", sans-serif;
  font-size: 17px; color: #3c5a4c; margin-bottom: 10px;
}
.rg-score b { font-size: 26px; color: #2e8b62; }
.rg-par { color: #8aa094; font-size: 14px; }
.rg-par b { font-size: 17px; color: #8aa094; }
#rg-stage-grid, #mg-stage-grid, #cg-stage-grid {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 7px; margin-bottom: 16px;
  max-height: 190px; overflow-y: auto;
}
.rg-cell {
  border: none; cursor: pointer;
  aspect-ratio: 1;
  border-radius: 10px;
  background: #e2f0e6;
  color: #3da368;
  font-family: "Jua", sans-serif; font-size: 14px;
  display: flex; align-items: center; justify-content: center;
}
.rg-cell.cleared { background: linear-gradient(135deg, #7fd3a4, #4bae7a); color: #fff; }
.rg-cell.locked { background: #e6ede8; color: #b8c6bd; cursor: not-allowed; }
.rg-cell.current { box-shadow: 0 0 0 3px #ffc46b; }

/* ---------- 온보딩 하이라이트 ---------- */
.ob-hi {
  position: relative;
  z-index: 29;
  animation: ob-pulse 1.3s ease-in-out infinite;
}
@keyframes ob-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,196,107,0.9), 0 4px 14px rgba(0,0,0,0.18); }
  50% { box-shadow: 0 0 0 10px rgba(255,196,107,0), 0 4px 14px rgba(0,0,0,0.18); }
}
#marimo.ob-hi, #marimo-mini.ob-hi {
  filter: drop-shadow(0 0 14px rgba(255,220,120,0.95));
  animation: ob-glow 1.3s ease-in-out infinite;
}
@keyframes ob-glow {
  0%, 100% { filter: drop-shadow(0 0 8px rgba(255,220,120,0.7)); }
  50% { filter: drop-shadow(0 0 20px rgba(255,230,150,1)); }
}

/* ---------- 다음 목표 칩 ---------- */
/* 다음 목표 — HUD 둘째 줄, 크기 배지 옆 남는 폭을 다 쓴다.
   무대 위에 띄우면 어항과 캐릭터 말풍선을 가린다. */
/* 다음 목표 — HUD 둘째 줄, 크기 배지 옆 남는 폭을 다 쓴다.
   무대 위에 띄우면 어항과 캐릭터 말풍선을 가린다.
   다른 알약(젬·크기·시간)과 같은 모양으로 두고, 글자만 강조색으로 띄운다.
   라벨을 붙이는 대신 색으로 "지금 할 일"임을 알린다. */
#goal-chip {
  flex: 0 1 auto;
  min-width: 0;
  background: rgba(255,255,255,0.85);
  border-radius: 999px;
  padding: 3px 13px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  display: flex; align-items: baseline;
}
#goal-text {
  font-family: "Noto Sans KR", sans-serif;
  font-size: 12px; font-weight: 700;
  color: #2e8b62;              /* 게임 강조색. 라벨 대신 색으로 "할 일"임을 알린다 */
  line-height: 1.35;
  min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#goal-chip.hidden { display: none; }
/* 좁은 화면에서는 시간 옆 설명(낮/밤·자는 중)을 접는다.
   시계와 아이콘만으로 충분하고, 마리모가 자는 건 그림으로도 보인다. */
@media (max-width: 429px) {
  .time-label { display: none; }
}
/* ---------- 액션 버튼 상태 ---------- */
.action-btn { position: relative; }
.action-btn.locked { opacity: 0.42; filter: grayscale(0.5); }
.action-btn.ready::after {
  content: "";
  position: absolute; top: 7px; right: 7px;
  width: 9px; height: 9px; border-radius: 50%;
  background: #ff6b6b;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.9);
  animation: badge-pop 1.4s ease-in-out infinite;
}
.badge-count {
  position: absolute; top: 5px; right: 6px;
  background: #ffc46b; color: #5a3a06;
  border-radius: 999px;
  min-width: 18px; height: 18px;
  font-size: 11px; line-height: 18px; text-align: center;
  font-weight: bold;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.9);
  padding: 0 4px;
}
.badge-count.empty { background: #c3cfc6; color: #6d7c72; }
.badge-dot {
  position: absolute; top: 7px; right: 7px;
  width: 9px; height: 9px; border-radius: 50%;
  background: #ff6b6b;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.9);
  animation: badge-pop 1.4s ease-in-out infinite;
}

/* ---------- 스트릭 ---------- */
#streak-dots {
  display: flex; justify-content: center; gap: 5px;
  margin-bottom: 16px; flex-wrap: wrap;
}
.sd {
  width: 26px; height: 26px; border-radius: 50%;
  background: #e6ede8; color: #a5b5ab;
  font-family: "Jua", sans-serif; font-size: 12px;
  line-height: 26px; text-align: center;
}
.sd.on { background: linear-gradient(135deg, #7fd3a4, #4bae7a); color: #fff; }
.sd.now {
  box-shadow: 0 0 0 3px rgba(255,196,107,0.75);
  transform: scale(1.12);
}
.streak-next {
  font-size: 12.5px !important; color: #7b8d80 !important;
  margin-bottom: 16px !important;
}
.streak-next b { color: #e08a1e; }

/* ---------- 분열 결과 ---------- */
.split-warn {
  font-size: 12px !important; color: #c98b2e !important;
  background: #fff6e4; border-radius: 10px;
  padding: 8px 12px; margin-bottom: 14px !important;
}
.split-img {
  width: 130px; height: 130px; object-fit: contain;
  margin: 4px auto 8px; display: block;
  animation: split-pop 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes split-pop {
  0% { transform: scale(0.2) rotate(-25deg); opacity: 0; }
  60% { transform: scale(1.14) rotate(6deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); }
}
.split-name {
  font-family: "Jua", sans-serif; font-size: 20px;
  color: #2e8b62; margin-bottom: 6px;
}
.split-tag {
  display: inline-block;
  font-size: 12px; color: #7b8d80;
  background: #eef3ef; border-radius: 999px;
  padding: 4px 14px; margin-bottom: 16px;
}
.split-tag.is-new {
  background: linear-gradient(135deg, #ffd97a, #f0a13a);
  color: #5a3a06; font-weight: bold;
}
#split-go:disabled { background: #c3cfc6; box-shadow: none; }

/* ---------- 도감 ---------- */
#album-items {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px; margin-bottom: 16px;
}
.album-cell {
  background: #f1f6ef; border-radius: 14px;
  padding: 8px 4px 6px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
}
.album-cell img { width: 52px; height: 52px; object-fit: contain; }
.album-cell span {
  font-family: "Noto Sans KR", sans-serif;
  font-size: 10.5px; color: #55685d; text-align: center; line-height: 1.3;
}
.album-cell.locked img { filter: brightness(0) opacity(0.16); }
.album-cell.locked span { color: #a5b5ab; }
.album-cell.current {
  background: #e2f6e8;
  box-shadow: inset 0 0 0 2px #7fd3a4;
}

.hidden { display: none !important; }

/* ---------- 함께 키우는 마리모 ---------- */
.buddy-layer { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.buddy {
  position: absolute;
  transform: translate(-50%, -50%);
  object-fit: contain;
  animation: buddy-bob 5.2s ease-in-out infinite;
  filter: drop-shadow(0 3px 5px rgba(40,70,80,0.22));
}
@keyframes buddy-bob {
  0%, 100% { transform: translate(-50%, -50%) rotate(-2deg); }
  50% { transform: translate(-50%, -58%) rotate(3deg); }
}

/* 함께 키울 마리모 고르기 */
.slot-pick { margin-top: 6px; }
.slot-pick-label {
  font-family: "Noto Sans KR", sans-serif;
  font-size: 11.5px; color: #7b8d80; margin-bottom: 6px; text-align: center;
}
.slot-row { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 6px; }
.slot-chip {
  border: none; cursor: pointer;
  font-family: inherit; font-size: 11.5px;
  background: #eef3ef; color: #55685d;
  border-radius: 999px; padding: 5px 11px;
}
.slot-chip.on {
  background: linear-gradient(135deg, #5cbf83, #3da368);
  color: #fff;
}

/* 도감에서 바로 키우기 */
.album-pick {
  border: none; cursor: pointer;
  font-family: inherit; font-size: 10.5px;
  background: linear-gradient(135deg, #57b7d8, #3a92c4);
  color: #fff;
  border-radius: 999px; padding: 3px 10px; margin-top: 2px;
}
.album-pick.on {
  background: #8dc79f; color: #2c4a3a;
}
.album-pick:disabled { cursor: default; }

/* ── 오늘의 미션: 접힌 상태가 기본 ──────────────────────────────
   작은 화면에서는 펼쳐진 목록이 마리모를 거의 다 가려서, 접어두고
   테두리를 깜빡여 눌러보게 유도한다. 한 번 열어보면 깜빡임은 멈춘다. */
#quest-toggle {
  border: 2px solid transparent;
  transition: border-color 0.2s;
}
#quest-caret {
  font-size: 11px; color: #5b7a68;
  transition: transform 0.2s;
}
#quest-toggle.open #quest-caret { transform: rotate(180deg); }
#quest-toggle.attract {
  border-color: #f5c033;
  animation: quest-attract 1.5s ease-in-out infinite;
}
/* 번쩍이지 않고 노란 테두리에서 링이 부드럽게 퍼져 나가게 한다.
   눈에는 띄되 아이가 놀라지 않도록. */
@keyframes quest-attract {
  0%, 100% { box-shadow: 0 2px 10px rgba(0,0,0,0.18), 0 0 0 0 rgba(245,192,51,0.55); }
  70%      { box-shadow: 0 2px 10px rgba(0,0,0,0.18), 0 0 0 9px rgba(245,192,51,0); }
}
@media (prefers-reduced-motion: reduce) {
  #quest-toggle.attract { animation: none; }
}

/* 미션이 늘어나 목록이 길어졌다. 화면을 덮지 않도록 안에서 스크롤시킨다. */
#quest-list {
  max-height: 52vh;
  overflow-y: auto;
  scrollbar-width: thin;
}
/* 시작 미션 — 딱 한 번만 나오는 것이라 눈에 띄게 */
.quest.starter {
  background: rgba(255,250,232,0.96);
  box-shadow: 0 2px 10px rgba(0,0,0,0.16), inset 0 0 0 2px rgba(245,192,51,0.55);
}
.quest .qtag {
  align-self: flex-start;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.04em;
  color: #8a6414; background: rgba(245,192,51,0.32);
  border-radius: 999px; padding: 1px 7px;
}

/* 도감 안내 — 카드로 새 마리모를 받으면 마리모가 곧바로 바뀐다.
   되돌리거나 골라 키우는 곳이 도감이라는 걸 알려주려고 책을 노랗게 빛낸다.
   테두리 대신 outline 을 쓰는 이유는 버튼 크기가 밀리지 않게 하기 위함. */
.chip-btn.attract {
  outline: 2px solid #f5c033;
  outline-offset: -1px;
  animation: quest-attract 1.5s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .chip-btn.attract { animation: none; }
}

/* 도감 — 마리모마다 크기가 따로라 어디까지 키웠는지 보여준다 */
.album-mm {
  font-size: 10px; color: #7d9c8b; font-variant-numeric: tabular-nums;
  margin-top: -2px;
}
.album-cell.current .album-mm { color: #4c9a6a; font-weight: 700; }

/* ---------- 미니게임 3: 마리모 합치기 ---------- */
#mergegame {
  position: absolute; inset: 0;
  z-index: 60;
  /* 어항 속이라는 걸 색으로 먼저 알린다 — 위는 햇빛, 아래는 깊은 물 */
  background: linear-gradient(180deg, #bdeaf5 0%, #7fc9de 45%, #4e9fbc 100%);
  overflow: hidden;
  touch-action: none;
}
#mrg-canvas {
  position: absolute;
  left: 0; right: 0; top: 0; bottom: 0;
  width: 100%; height: 100%;
  display: block;
}
#mrg-hud {
  position: absolute; top: 8px; left: 8px; right: 56px;
  display: flex; align-items: center; gap: 8px;
  z-index: 2; pointer-events: none;
}
.mrg-next {
  margin-left: auto;
  display: flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.88);
  border-radius: 999px; padding: 3px 10px 3px 12px;
  font-size: 11px; color: #3c5a4c;
}
.mrg-next img { width: 26px; height: 26px; object-fit: contain; }

/* 햇빛 게이지 — 다 차면 눌러서 작은 마리모들을 광합성시킨다 */
.mrg-sun {
  position: absolute; right: 10px; bottom: 14px;
  width: 62px; height: 62px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.85);
  background: rgba(255,255,255,0.28);
  overflow: hidden; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  z-index: 3;
  transition: transform 0.15s;
}
.mrg-sun[disabled] { opacity: 0.55; cursor: default; }
.mrg-sun.ready {
  border-color: #ffd452;
  box-shadow: 0 0 0 0 rgba(255,212,82,0.7);
  animation: mrg-sun-pulse 1.4s ease-out infinite;
}
@keyframes mrg-sun-pulse {
  0% { box-shadow: 0 0 0 0 rgba(255,212,82,0.7); }
  100% { box-shadow: 0 0 0 14px rgba(255,212,82,0); }
}
.mrg-sun-fill {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 0%;
  background: linear-gradient(180deg, #ffe9a8, #ffc93c);
  transition: height 0.25s ease;
}
.mrg-sun-icon { position: relative; font-size: 24px; line-height: 1; }

/* 새 품종을 처음 만들었을 때 이름을 띄운다 */
.mrg-toast {
  position: absolute; left: 50%; top: 24%;
  transform: translateX(-50%);
  background: rgba(255,255,255,0.95);
  border-radius: 999px; padding: 7px 18px;
  font-family: "Jua", "Noto Sans KR", sans-serif;
  font-size: 15px; color: #3c5a4c;
  box-shadow: 0 4px 14px rgba(0,0,0,0.18);
  z-index: 4;
  animation: mrg-toast-in 0.3s ease;
}
@keyframes mrg-toast-in {
  from { opacity: 0; transform: translate(-50%, 8px) scale(0.9); }
  to { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

/* 시작 화면의 합체 사슬 미리보기 */
#mrg-chain {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 3px;
  margin: 10px 0 6px;
}
#mrg-chain img { object-fit: contain; }
#mrg-chain span { color: var(--ink-soft, #7d9c8b); font-size: 11px; }
.mrg-tip {
  font-size: 12px; color: #7d9c8b; line-height: 1.5;
  margin: 4px 0 12px;
}
.mrg-newbest {
  font-family: "Jua", sans-serif; color: #e0a43c; font-size: 15px; margin: 4px 0;
}

/* 합치기 목표 — 스테이지 대신 한 번씩만 달성하는 목표들 */
#mrg-goals {
  display: flex; flex-direction: column; gap: 3px;
  margin: 2px 0 12px;
  max-height: 30vh; overflow-y: auto;
}
.mrg-goal {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12px; color: #55685d;
  background: rgba(0,0,0,0.035);
  border-radius: 8px; padding: 4px 10px;
}
.mrg-goal b { color: #4c9a6a; font-size: 11px; }
.mrg-goal.on { color: #4c9a6a; background: rgba(76,154,106,0.12); }
.mrg-goal.on b { opacity: 0.5; }

/* ---------- 화면을 눕혔을 때 ----------
   세로 화면 기준으로 만든 배치라, 높이가 짧아지면 HUD 와 버튼이 공간을 다
   먹고 어항이 눌린다. 데스크톱(720 이상)은 문제없고 폰을 눕혔을 때만 해당한다.
   요소를 없애지 않고 크기만 줄여, 보이는 것은 같게 두면서 어항에 공간을 준다. */
@media (max-height: 560px) {
  #hud { padding: 6px 10px 0; }
  /* 젬·크기·시각을 세로로 쌓지 않고 한 줄로 늘어놓아 높이를 아낀다 */
  .hud-left { flex-direction: row; align-items: center; gap: 5px; }
  .gem-counter { font-size: 15px; padding: 2px 11px 2px 5px; }
  .gem-counter img { width: 18px; height: 18px; }
  #meters { padding: 5px 10px 4px; gap: 6px; }
  .meter { padding: 3px 8px 4px; }
  /* v2.7: 낮은 화면에서 상태명이 너무 작다는 검수 지적. 키우고 색도 진하게. */
  .meter-label { font-size: 11px; color: #3f5a4c; margin-bottom: 2px; }
  .meter-bar { height: 5px; }
  #actions { padding: 4px 10px calc(6px + env(safe-area-inset-bottom)); gap: 7px; }
  .action-btn { width: 54px; height: 56px; border-radius: 16px; font-size: 10px; gap: 0; }
  .action-btn img { width: 26px; height: 26px; }
  .action-btn .btn-emoji { font-size: 22px; line-height: 26px; }
  #quest-panel { top: 4px; }
  #quest-toggle { font-size: 11px; padding: 4px 10px; }
  #play-timer { bottom: 126px; }
}

/* 함께 키우는 마리모도 눌러서 쓰다듬을 수 있게 한다.
   buddy-bob 이 transform 을 쓰고 있어서, 눌렸을 때 애니메이션도
   translate 를 유지해야 자리가 튀지 않는다. */
.buddy { pointer-events: auto; cursor: pointer; }
.buddy.tapped { animation: buddy-tap 0.54s ease; }
@keyframes buddy-tap {
  0%, 100% { transform: translate(-50%, -50%) rotate(0deg) scale(1); }
  22% { transform: translate(-50%, -50%) rotate(-7deg) scale(1.09); }
  55% { transform: translate(-50%, -50%) rotate(6deg) scale(0.96); }
  80% { transform: translate(-50%, -50%) rotate(-3deg) scale(1.03); }
}

/* 안내 문구는 눌러서 바로 치울 수 있다 */
#tip { cursor: pointer; }

/* dev-only:start */
/* ---------- 개발 도구 ----------
   HUD 의 빈 자리를 빠르게 일곱 번 두드려야 열린다. 우연히 열릴 일은 없다. */
.cheat-card { max-width: 420px; }
.cheat-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 7px;
  margin: 12px 0 16px;
  max-height: 46vh; overflow-y: auto;
}
.cheat-grid button {
  border: 1px solid var(--line, #d5e2d8);
  background: rgba(0,0,0,0.03);
  border-radius: 10px; padding: 9px 8px;
  font-family: inherit; font-size: 12px; color: #3c5a4c;
  cursor: pointer;
}
.cheat-grid button:active { transform: scale(0.96); }
.cheat-grid button.danger { color: #c0392b; border-color: #e8bcb4; }
#cheat-state {
  font-family: "IBM Plex Mono", Consolas, monospace;
  font-size: 11px; word-break: break-all;
}

/* 녹화 모드 — 영상에 담고 싶지 않은 안내 요소를 감춘다.
   개발 도구에서만 켤 수 있다. */
#game.recording #quest-panel,
#game.recording #goal-chip,
#game.recording #tip,
#game.recording #play-timer,
#game.recording #view-dots,
#game.recording .view-hint,
#game.recording #btn-reset { display: none !important; }
/* dev-only:end */

/* 언어 선택 */
.lang-card { max-width: 360px; }
.lang-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin: 14px 0 16px; }
.lang-grid button {
  border: 1px solid var(--line, #d5e2d8);
  background: rgba(0,0,0,0.03);
  border-radius: 10px; padding: 10px 8px;
  font-family: inherit; font-size: 13px; color: #3c5a4c; cursor: pointer;
}
.lang-grid button.on {
  background: rgba(76,154,106,0.14);
  border-color: #4c9a6a; color: #2e6e64; font-weight: 700;
}

/* ---------- 데스크톱 좌우 패널 ----------
   세로 전용 게임을 넓은 화면에서 열면 가운데 640px 만 쓰고 좌우가 텅 빈다.
   폰 화면을 데스크톱에 붙여둔 것처럼 보인다.

   어항 아트를 가로로 늘리는 방법도 있지만, 장식이 % 로 배치돼 있어
   벌어지고 마리모가 작아 보인다. 무대는 640 그대로 두고 빈 자리에
   내용을 채운다.

   기존 오버레이(#tip, #speech, #view-dots, 모달)는 전부 #game 기준
   절대 위치라 흐름에서 빠져 있다. #game 을 가로 배치로 바꿔도
   영향이 없고, 좌우 패널 폭이 같아 left:50% 도 무대 중앙에 맞는다. */
.side-panel { display: none; }
/* 좁은 화면에서는 무대가 화면을 다 채우므로 배경이 보일 일이 없다. */
#ambient { display: none; }

/* 무대는 640px 이라 화면이 그보다 넓어지는 순간부터 좌우가 빈다.
   좌우 패널(980px~)보다 먼저 켜야 907x510 같은 작은 데스크톱 프레임에서도
   빈자리가 생기지 않는다. 규정이 검사하는 크기 중 가장 작은 값이다.

   hover:hover 로 막아둔 이유 — 폰을 눕히면 844x390 이 되어 이 조건에
   걸린다. 그러면 배경이 좌우를 채워 화면 전체가 가로형으로 읽힌다.
   세로 게임으로 낸 것이라 그러면 안 된다. 마우스가 있는 기기에서만 켠다. */
@media (min-width: 720px) and (hover: hover) {
  /* 흐린 방 사진 한 장. inset 을 음수로 줘서 블러가 만든 흐린 가장자리가
     화면 안으로 들어오지 않게 한다. */
  #ambient {
    display: block;
    position: fixed; inset: -60px;
    background: url("../assets/bg-window.webp") center 35% / cover no-repeat;
    filter: blur(52px) saturate(0.95) brightness(0.72);
    transition: filter 2s ease;
    z-index: 0;
  }
  /* 가장자리로 갈수록 어둡게. 무대가 앞으로 나와 보이고 화면 끝이 정리된다.
     가운데는 무대가 덮으므로 밝게 둬도 된다 — 어둡게 깔면 그냥 검은 화면이 된다. */
  #ambient::after {
    content: ""; position: absolute; inset: 0;
    background: radial-gradient(ellipse 62% 78% at 50% 44%,
      rgba(12,24,19,0) 0%, rgba(12,24,19,0.30) 58%, rgba(12,24,19,0.72) 100%);
  }
  /* 방과 같이 밤이 든다. 무대만 밤이고 바깥은 낮이면 어긋나 보인다. */
  body.night #ambient {
    filter: blur(52px) saturate(0.7) brightness(0.34) hue-rotate(-20deg);
  }
  body.sunny #ambient {
    filter: blur(52px) saturate(1.05) brightness(0.86);
  }
  #game { z-index: 1; }
  /* 무대를 배경에서 떼어 놓는다. 경계가 없으면 흐린 배경과 붙어 보인다. */
  #stage-col {
    box-shadow: 0 0 0 1px rgba(255,255,255,0.07),
                0 24px 70px rgba(0,0,0,0.55);
  }
}

@media (min-width: 980px) {
  #game {
    /* 패널 폭을 한 곳에서 정한다. 무대에 붙어 있는 것들(목표 칩, 타이머,
       스와이프 안내)이 이 값을 따라가야 해서 변수로 둔다. */
    --panel: 180px;
    max-width: calc(640px + var(--panel) * 2);
    flex-direction: row;
    justify-content: center;
    align-items: stretch;
    gap: 0;
  }
  #stage-col {
    width: 640px; flex: none;
    display: flex; flex-direction: column;
    min-height: 0;
    order: 2;
  }
  /* 마크업에서는 무대가 먼저 온다. 화면에서는 왼쪽 패널이 앞이다. */
  #side-left { order: 1; }
  #side-right { order: 3; }
  /* 흐린 방 위에 흰 글씨를 그냥 얹으면 묻힌다. 무대 쪽이 짙고 바깥으로
     갈수록 옅어지는 판을 깔아 글씨 대비를 확보하면서, 패널이 무대에
     붙어 있는 한 덩어리로 읽히게 한다. */
  #side-left {
    background: linear-gradient(to left,
      rgba(10,20,16,0.70) 0%, rgba(10,20,16,0.36) 58%, rgba(10,20,16,0) 100%);
  }
  #side-right {
    background: linear-gradient(to right,
      rgba(10,20,16,0.70) 0%, rgba(10,20,16,0.36) 58%, rgba(10,20,16,0) 100%);
  }
  .side-panel {
    display: flex; flex-direction: column;
    /* 내용이 400px 남짓이라 위로 붙이면 아래가 뭉텅 빈다.
       가운데로 모으면 남는 자리가 위아래로 나뉘어 여백으로 읽힌다. */
    justify-content: center;
    width: var(--panel); flex: none;
    padding: 16px 12px;
    gap: 10px;
    overflow-y: auto;
    scrollbar-width: thin;
  }
  .side-title {
    font-family: inherit; font-weight: normal;
    font-size: 12px; letter-spacing: .04em;
    color: rgba(255,255,255,0.80);
    padding-left: 2px;
  }

  /* 왼쪽 — 기록 */
  .side-row {
    background: rgba(255,255,255,0.11);
    border-radius: 12px;
    padding: 8px 11px;
    display: flex; flex-direction: column; gap: 2px;
  }
  .side-k { font-size: 11px; color: rgba(255,255,255,0.74); }
  .side-v { font-size: 15px; color: #eaf4ee; }

  /* 오른쪽 — 도감 */
  #side-album {
    display: grid; grid-template-columns: 1fr 1fr; gap: 7px;
  }
  .side-cell {
    background: rgba(255,255,255,0.11);
    border-radius: 11px;
    padding: 6px 3px 5px;
    display: flex; flex-direction: column; align-items: center; gap: 2px;
  }
  .side-cell img { width: 44px; height: 44px; object-fit: contain; }
  .side-cell.locked img { filter: grayscale(1) brightness(0.45); }
  .side-cell span {
    font-size: 9.5px; color: rgba(255,255,255,0.78);
    text-align: center; line-height: 1.25;
  }
  .side-cell.on { background: rgba(140,220,175,0.16); }
  .side-cta {
    margin-top: 2px;
    font-family: inherit; font-size: 12px;
    color: #d9efe1; cursor: pointer;
    background: rgba(255,255,255,0.09);
    border: none; border-radius: 10px; padding: 7px;
  }
  .side-cta:hover { background: rgba(255,255,255,0.15); }

  /* 무대 기준으로 붙어 있던 것들을 패널 폭만큼 밀어준다 */
  #play-timer { right: calc(var(--panel) + 12px); }
  .view-hint { right: calc(var(--panel) + 12px); }
  .view-hint.right { right: auto; left: calc(var(--panel) + 12px); }
}

/* 화면이 더 넓어지면 패널을 키운다. 무대는 640 그대로 둔다 —
   어항 장식이 % 로 배치돼 있어 무대를 늘리면 사이가 벌어지고,
   유리병은 widthPx 로 상한이 걸려 있어 커지지도 않는다. */
@media (min-width: 1280px) {
  #game { --panel: 240px; }
  .side-panel { padding: 20px 16px; gap: 12px; }
  .side-row { padding: 10px 13px; }
  .side-k { font-size: 12px; }
  .side-v { font-size: 17px; }
  .side-cell img { width: 56px; height: 56px; }
  .side-cell span { font-size: 11px; }
  .side-title { font-size: 13px; }
}
@media (min-width: 1600px) {
  #game { --panel: 300px; }
  #side-album { grid-template-columns: 1fr 1fr; gap: 10px; }
  .side-cell { padding: 9px 4px 7px; }
  .side-cell img { width: 68px; height: 68px; }
  .side-v { font-size: 18px; }
}

/* 온보딩 건너뛰기. 가이드라인이 건너뛸 수 있어야 한다고 못박고 있다.
   안내 자체에 붙여야 눈에 띈다. */
#tip { display: flex; align-items: center; gap: 10px; }
#tip-skip {
  flex: none;
  font-family: inherit; font-size: 11px;
  color: rgba(255,255,255,0.7);
  background: rgba(255,255,255,0.14);
  border: none; border-radius: 999px;
  padding: 3px 10px;
  cursor: pointer;
}
#tip-skip:hover { background: rgba(255,255,255,0.24); color: #fff; }
#tip-skip.hidden { display: none; }

/* ===== v2: 마리모 들어 옮기기 =====
   행동 애니메이션(.b-*)은 transform 을 쓰므로 위치는 left/top 으로 옮긴다.
   손에 들려 있는 동안은 애니메이션을 멈추고, 놓으면 top 만 천천히 내려가 가라앉는다. */
#marimo { touch-action: none; }
#marimo.held, .cos-wrap.held {
  animation: none !important;
  transition: none !important;
  transform: translate(-50%, -50%) scale(1.06) !important;
  filter: drop-shadow(0 10px 10px rgba(0, 40, 60, 0.28));
  z-index: 6;
  cursor: grabbing;
}
#marimo.settling, .cos-wrap.settling {
  transition: top 1.7s cubic-bezier(0.25, 0.7, 0.2, 1), left 1.7s cubic-bezier(0.25, 0.7, 0.2, 1), width 1s ease;
}

/* 장식 기포 — 젬이 안 나오는 작은 물방울. 어항이 살아 있어 보이게만 한다 */
.bubble.ambient {
  pointer-events: none;
  cursor: default;
  opacity: 0.55;
  border-color: rgba(255, 255, 255, 0.35);
  animation-timing-function: ease-out;
}

/* 온보딩 중에는 미션 패널을 감춘다 — 핵심 고리를 익힌 뒤에 팝 하고 나타난다.
   스와이프 안내(.view-hint)는 숨기지 않는다. 첫 화면이 방이라, 어항으로 넘어가는 유일한 단서다. */
#game.onboarding #quest-panel { display: none; }
#quest-panel.reveal { animation: badge-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }

/* ===== v2 수정: 안내 말풍선의 Skip 이 안 눌리던 문제 =====
   #tip 에 pointer-events:none 이 걸려 있어(마리모를 가리지 않으려던 초기 설정)
   그 안의 Skip 버튼도 상속으로 눌리지 않았다. 나중에 "눌러서 치우기"와 Skip 핸들러,
   cursor:pointer 까지 붙였지만 이 한 줄을 풀지 않아 전부 죽어 있었다.
   가이드라인이 온보딩은 건너뛸 수 있어야 한다고 못박고 있는데, 제출본 두 번 다 안 눌렸다. */
#tip { pointer-events: auto; }
#tip-skip { pointer-events: auto; }

/* ---------- 확률 공개 (v2.4) ---------- */
.link-btn {
  background: none; border: none; color: #2e8b62; text-decoration: underline;
  font-size: 12px; padding: 2px 8px 10px; cursor: pointer; font-family: inherit;
}
#odds-list { margin: 6px 0 14px; max-height: 46vh; overflow-y: auto; }
.odds-row {
  display: flex; align-items: center; gap: 10px; padding: 6px 2px;
  border-bottom: 1px solid #eef3ef; font-size: 14px; color: #3f5a4c;
}
.odds-row img { width: 32px; height: 32px; object-fit: contain; }
.odds-row span { flex: 1; text-align: left; }
.odds-row b { color: #2e8b62; font-variant-numeric: tabular-nums; }
.odds-note { font-size: 12px; color: #7b8d80; line-height: 1.5; margin-top: 10px; text-align: left; }

/* ---------- 미니게임 4: 어항 청소 ---------- */
#cleangame {
  position: absolute; inset: 0;
  z-index: 60;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.22), rgba(255,255,255,0) 26%,
                    rgba(70,160,190,0) 55%, rgba(60,150,185,0.45) 100%),
    url("../assets/bg-underwater.webp") center bottom / cover no-repeat,
    linear-gradient(180deg, #a5e4f0 0%, #7cc9e0 45%, #55a8cc 100%);
  overflow: hidden;
}
#cg-canvas {
  position: absolute;
  left: 0; right: 0;
  top: 62px; bottom: 0;
  width: 100%;
  height: calc(100% - 62px);
  touch-action: none;
  display: block;
}
#cg-hud {
  position: absolute;
  top: 12px; left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 10px;
  z-index: 3;
}
#cg-hint {
  position: absolute;
  bottom: 18px; left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  background: rgba(20,45,55,0.55);
  color: #fff;
  font-family: "Noto Sans KR", sans-serif;
  font-size: 12.5px;
  border-radius: 999px;
  padding: 6px 16px;
  pointer-events: none;
  animation: hint-pulse 2.4s ease-in-out infinite;
}
/* 어항 식구가 도와줄 때만 잠깐 뜬다 */
.cg-toast {
  position: absolute;
  top: 72px; left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  background: rgba(46, 139, 98, 0.92);
  color: #fff;
  font-family: "Jua", sans-serif;
  font-size: 14px;
  border-radius: 18px;
  padding: 7px 18px;
  pointer-events: none;
  box-shadow: 0 4px 14px rgba(0,0,0,0.2);
  transition: opacity 0.25s;
  /* 열 개 언어가 들어온다. 좁은 화면에서 낱말 가운데가 잘리지 않게 한다. */
  max-width: 86%;
  text-align: center;
  word-break: keep-all;
  line-height: 1.35;
}
.cg-toast.hidden { display: none; }
