/* 서바이벌 OX 맵의 살아 있는 움직임(2026-10-26 사용자 고름). ox-survival.css 다음에 불러온다(index.html).
   - 숲속: 꽃 머리·덤불 윗부분이 바람에 한 점씩 좌우로(장면 2장), 나비 셋이 꽃밭 둘레를 팔랑, 가끔 잎이 마당을 가로질러 날아감.
   - 용암 공장: 압력계 둘(배경 압력계를 떼어 옮김)의 바늘이 덜덜, 밸브에서 가끔 김이 폭, 기계 위 빨간 경고등이 깜빡
     (마지막 3초에는 빠르게), 아래 양옆에서 불티가 올라옴.
   경기장 좌표는 1680×720(ox-survival.js A). 그림은 배경(2016×864)과 같은 비율이라 크기·자리는 원화 화소 × 1680/2016(--k).
   문제판(가운데 위 x 450~1230, y 0~290)에 가리지 않는 양옆 벽에만 둔다. 도트라 pixelated, 움직임은 steps(),
   숨은 탭·창에서는 멈추고 동작 줄이기에서는 보이지 않는다. 그림 만들기 tools/ox/ox-map-fx.py. */
.ox-mapfx { position: absolute; inset: 0; z-index: 1; pointer-events: none; --k: .8333; }
.ox-mapfx > i { display: none; position: absolute; image-rendering: pixelated; background: 0 0 / auto 100% no-repeat; }

/* ── 숲속: 꽃·덤불 살랑(가운데 → 오른쪽 → 가운데 → 왼쪽) ── */
.ox-room[data-map="forest"] .ox-arena::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: center / 100% 100% no-repeat; animation: ox-fx-sway 3.6s steps(1, end) infinite;
}
@keyframes ox-fx-sway {
  0%, 50%, 100% { background-image: none; }
  25% { background-image: url("./assets/ox-survival/fx/forest-sway-1.webp"); }
  75% { background-image: url("./assets/ox-survival/fx/forest-sway-2.webp"); }
}

/* ── 숲속: 나비 셋(날개 펴짐·접힘 두 장 + 꽃밭 둘레 길) ── */
.ox-room[data-map="forest"] .ox-mapfx > i:nth-child(-n+3) {
  display: block; width: calc(45px * var(--k)); height: calc(30px * var(--k));
  background-size: calc(90px * var(--k)) 100%;
  animation: ox-fx-flap .32s steps(1, end) infinite, var(--path) var(--dur) steps(var(--st), end) infinite;
}
.ox-room[data-map="forest"] .ox-mapfx > i:nth-child(1) { background-image: url("./assets/ox-survival/fx/fly-pink.webp"); left: 250px; top: 120px; --path: ox-fx-fly1; --dur: 9s; --st: 60; }
.ox-room[data-map="forest"] .ox-mapfx > i:nth-child(2) { background-image: url("./assets/ox-survival/fx/fly-yellow.webp"); left: 1490px; top: 240px; --path: ox-fx-fly2; --dur: 11s; --st: 72; animation-delay: -.1s, -3s; }
.ox-room[data-map="forest"] .ox-mapfx > i:nth-child(3) { background-image: url("./assets/ox-survival/fx/fly-white.webp"); left: 80px; top: 340px; --path: ox-fx-fly3; --dur: 13s; --st: 84; animation-delay: -.2s, -6s; }
@keyframes ox-fx-flap { 0% { background-position: 0 0; } 50% { background-position: calc(-45px * var(--k)) 0; } }
@keyframes ox-fx-fly1 { 0%, 100% { translate: 0 0; } 20% { translate: 70px -18px; } 40% { translate: 110px 40px; } 55% { translate: 60px 80px; } 75% { translate: 10px 50px; } 90% { translate: -20px 10px; } }
@keyframes ox-fx-fly2 { 0%, 100% { translate: 0 0; } 15% { translate: 60px 30px; } 35% { translate: 120px 110px; } 55% { translate: 70px 160px; } 75% { translate: -10px 90px; } 90% { translate: 20px 30px; } }
@keyframes ox-fx-fly3 { 0%, 100% { translate: 0 0; } 20% { translate: 90px 60px; } 40% { translate: 120px 170px; } 60% { translate: 40px 230px; } 80% { translate: -10px 120px; } }

/* ── 숲속: 가끔 잎이 마당을 가로질러(세 방향 그림을 돌려 가며) ── */
.ox-room[data-map="forest"] .ox-mapfx > i:nth-child(4), .ox-room[data-map="forest"] .ox-mapfx > i:nth-child(5) {
  display: block; left: -40px; width: calc(25px * var(--k)); height: calc(20px * var(--k)); opacity: 0;
  background-size: calc(75px * var(--k)) 100%;
  animation: ox-fx-tumble .66s steps(1, end) infinite, var(--path) var(--dur) steps(var(--st), end) infinite;
}
.ox-room[data-map="forest"] .ox-mapfx > i:nth-child(4) { background-image: url("./assets/ox-survival/fx/leaf-green.webp"); top: 250px; --path: ox-fx-leaf1; --dur: 19s; --st: 190; }
.ox-room[data-map="forest"] .ox-mapfx > i:nth-child(5) { background-image: url("./assets/ox-survival/fx/leaf-yellow.webp"); top: 380px; --path: ox-fx-leaf2; --dur: 23s; --st: 230; animation-delay: -.3s, -11s; }
@keyframes ox-fx-tumble { 0% { background-position: 0 0; } 33% { background-position: calc(-25px * var(--k)) 0; } 66% { background-position: calc(-50px * var(--k)) 0; } }
@keyframes ox-fx-leaf1 { 0% { opacity: 1; translate: 0 0; } 10% { translate: 300px 40px; } 20% { translate: 620px 20px; } 30% { translate: 960px 90px; } 40% { translate: 1300px 70px; } 48% { opacity: 1; translate: 1760px 140px; } 48.1%, 100% { opacity: 0; translate: 1760px 140px; } }
@keyframes ox-fx-leaf2 { 0% { opacity: 1; translate: 0 0; } 12% { translate: 380px -30px; } 24% { translate: 760px 30px; } 36% { translate: 1120px 0; } 46% { opacity: 1; translate: 1760px 80px; } 46.1%, 100% { opacity: 0; translate: 1760px 80px; } }

/* ── 용암 공장: 압력계 둘, 바늘이 덜덜(네 장) ── */
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(-n+2) {
  display: block; width: calc(43px * var(--k)); height: calc(51px * var(--k));
  background-image: url("./assets/ox-survival/fx/gauge.webp"); background-size: calc(172px * var(--k)) 100%;
  animation: ox-fx-needle 2.6s steps(1, end) infinite;
}
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(1) { left: calc(339px * var(--k)); top: calc(77px * var(--k)); }
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(2) { left: calc(1633px * var(--k)); top: calc(139px * var(--k)); animation-delay: -1.1s; }
@keyframes ox-fx-needle {
  0%, 20%, 70% { background-position: calc(-43px * var(--k)) 0; } 10%, 30%, 55% { background-position: calc(-86px * var(--k)) 0; }
  42% { background-position: calc(-129px * var(--k)) 0; } 80% { background-position: 0 0; } 90% { background-position: calc(-43px * var(--k)) 0; }
}

/* ── 용암 공장: 밸브에서 가끔 김(네 장으로 커지며 흩어짐, 밸브마다 때를 어긋나게) ── */
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(n+3):nth-child(-n+5) {
  display: block; width: calc(60px * var(--k)); height: calc(30px * var(--k)); opacity: 0;
  background-image: url("./assets/ox-survival/fx/steam.webp"); background-size: calc(240px * var(--k)) 100%;
  animation: ox-fx-steam 5.2s steps(1, end) infinite;
}
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(3) { left: calc(450px * var(--k)); top: calc(32px * var(--k)); }
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(4) { left: calc(1590px * var(--k)); top: calc(42px * var(--k)); animation-delay: -2s; }
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(5) { left: calc(96px * var(--k)); top: calc(362px * var(--k)); animation-delay: -3.7s; }
@keyframes ox-fx-steam {
  0% { opacity: 1; translate: 0 0; background-position: 0 0; }
  5% { translate: 0 -3px; background-position: calc(-60px * var(--k)) 0; }
  10% { translate: 0 -7px; background-position: calc(-120px * var(--k)) 0; }
  15% { opacity: 1; translate: 0 -12px; background-position: calc(-180px * var(--k)) 0; }
  20%, 100% { opacity: 0; }
}

/* ── 용암 공장: 기계 위 빨간 경고등(켜짐·꺼짐), 마지막 3초(.hurry)에는 빠르게 ── */
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(6), .ox-room[data-map="factory"] .ox-mapfx > i:nth-child(7) {
  display: block; width: calc(35px * var(--k)); height: calc(30px * var(--k));
  background-image: url("./assets/ox-survival/fx/lamp.webp"); background-size: calc(70px * var(--k)) 100%;
  animation: ox-fx-lamp 1.6s steps(1, end) infinite;
}
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(6) { left: calc(62px * var(--k)); top: calc(518px * var(--k)); }
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(7) { left: calc(1928px * var(--k)); top: calc(205px * var(--k)); animation-delay: -.8s; }
.ox-room.hurry[data-map="factory"] .ox-mapfx > i:nth-child(6), .ox-room.hurry[data-map="factory"] .ox-mapfx > i:nth-child(7) { animation-duration: .4s; }
@keyframes ox-fx-lamp { 0% { background-position: 0 0; } 50% { background-position: calc(-35px * var(--k)) 0; } }

/* ── 용암 공장: 아래 양옆에서 올라오는 불티(1점 불티 띠를 위로 밀고, 위쪽으로 갈수록 사라짐) ── */
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(8), .ox-room[data-map="factory"] .ox-mapfx > i:nth-child(9) {
  display: block; top: 466px; width: calc(80px * var(--k)); height: 250px;
  background: url("./assets/ox-survival/fx/embers.webp") 0 0 / calc(80px * var(--k)) calc(300px * var(--k)) repeat-y;
  -webkit-mask-image: linear-gradient(#0000, #000 45%); mask-image: linear-gradient(#0000, #000 45%);
  animation: ox-fx-embers 3.4s steps(34, end) infinite;
}
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(8) { left: calc(70px * var(--k)); }
.ox-room[data-map="factory"] .ox-mapfx > i:nth-child(9) { left: calc(1850px * var(--k)); animation-delay: -1.5s; scale: -1 1; }
@keyframes ox-fx-embers { from { background-position: 0 0; } to { background-position: 0 calc(-300px * var(--k)); } }

/* ── 관중석 O·X 표시(움직임 아님, 2026-10-26 사용자 "관중석으로 가는데 어떻게 문제를 맞춰?"): 관중석은 왼쪽 절반 O·오른쪽 절반 X로
   채점되므로(ox-survival.js benchZone) 양끝에 O·X 원화, 가운데에 나눔 점선. 게임이 시작되면 보인다. 관중석 A.bench = x 220~1460, y 642~672 ── */
.ox-benchmark { display: none; position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.ox-room:not([data-phase="lobby"]) .ox-benchmark { display: block; }
/* 팻말 = 그 맵 문제판 원화를 작게(숲 나무 팻말·공장 철판 틀, 비율 그대로), 종이 칸(QPOxArt board.paper 자리)에 O·X 원화 */
.ox-benchmark i { position: absolute; top: 596px; width: 124px; height: 46px; background: 0 0 / 100% 100% no-repeat; }
.ox-room[data-map="forest"] .ox-benchmark i { background-image: url("./assets/ox-survival/ox-board-forest.webp"); }
.ox-room[data-map="factory"] .ox-benchmark i { height: 47px; background-image: url("./assets/ox-survival/ox-board-factory.webp"); }
.ox-benchmark i::after { content: ""; position: absolute; left: 4%; right: 7%; top: 8%; height: 58%; background: center / contain no-repeat; }
.ox-room[data-map="factory"] .ox-benchmark i::after { left: 8%; right: 8%; top: 9%; height: 62%; }
.ox-benchmark i.o { left: 108px; } .ox-benchmark i.o::after { background-image: url("./assets/quiz-marks/o.webp"); }
.ox-benchmark i.x { left: 1448px; } .ox-benchmark i.x::after { background-image: url("./assets/quiz-marks/x.webp"); }
.ox-benchmark b { position: absolute; left: 838px; top: 636px; width: 4px; height: 42px;
  background: repeating-linear-gradient(#ffffffd9 0 6px, #0000 6px 11px); }

/* 숨은 탭에서 멈추고, 동작 줄이기에서는 움직임을 보이지 않는다(원래 배경 그대로) */
html.qp-hidden :is(.ox-mapfx > i, .ox-room .ox-arena::before) { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .ox-mapfx { display: none; }
  .ox-room[data-map] .ox-arena::before { content: none; animation: none; }
}
