/* Native room plates and animation strips. Every layer shares one integer
   display scale and one origin. CSS selects cells; it never deforms the art. */
.battle-scenery { --native-pixel: 4px; --native-left: 0px; --native-top: 0px; --native-edge: 0px; }
.dungeon-scene.native-scene {
  left: var(--native-left); top: 0; width: calc(var(--native-width) * var(--native-pixel)); height: 100%;
  transform: none; overflow: hidden; background: var(--native-color);
  mask-image: linear-gradient(to right, transparent, #000 var(--native-edge), #000 calc(100% - var(--native-edge)), transparent);
}
.native-scene :is(img, .native-sheet, .native-drift, .native-ceiling, .native-ground) { image-rendering: pixelated; }
.native-stage { position: absolute; left: 0; top: var(--native-top); width: 100%; height: calc(var(--native-height) * var(--native-pixel)); }
.native-base { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.native-ceiling { position: absolute; inset: 0 0 auto; height: max(0px, var(--native-top)); background-size: 100% var(--native-pixel); background-repeat: repeat-y; }
.native-ground { position: absolute; inset: calc(var(--native-top) + var(--native-height) * var(--native-pixel)) 0 0; background-size: 100% auto; background-repeat: repeat-y; }
.native-ground-extended { background-size: 100% auto, 100% var(--native-pixel); background-repeat: no-repeat, repeat-y; }
.native-sheet {
  position: absolute; display: block;
  left: calc(var(--x) * var(--native-pixel)); top: calc(var(--y) * var(--native-pixel));
  width: calc(var(--frame-width) * var(--native-pixel)); height: calc(var(--frame-height) * var(--native-pixel));
  background-repeat: no-repeat;
  background-size: calc(var(--frames) * 100%) calc(var(--rows) * 100%);
  background-position: 0 calc(-1 * var(--row) * var(--frame-height) * var(--native-pixel));
  animation: native-frame-strip var(--period) steps(var(--frames), end) infinite;
  animation-delay: calc(var(--scene-clock) + var(--phase));
}
.native-sheet[data-frames="1"] { animation: none; }
.native-drift {
  position: absolute; display: block;
  left: calc(var(--x) * var(--native-pixel)); top: calc(var(--y) * var(--native-pixel));
  width: 100%; height: calc(var(--frame-height) * var(--native-pixel));
  background-repeat: repeat-x;
  background-size: calc(var(--frame-width) * var(--native-pixel)) calc(var(--frame-height) * var(--native-pixel));
  animation: native-drift var(--period) steps(var(--frame-width), end) infinite;
  animation-delay: calc(var(--scene-clock) + var(--phase));
}
@keyframes native-drift { to { background-position-x: calc(-1 * var(--frame-width) * var(--native-pixel)); } }
@keyframes native-frame-strip { to { background-position-x: calc(-1 * var(--frames) * var(--frame-width) * var(--native-pixel)); } }
/* A passing breeze, stronger second push, then a short elastic recovery.
   Select complete drawings from the earlier 4-pose grass atlas; the two root
   rows never move. Only Overgrowth grass uses this unequal exposure timing. */
.overgrowth-scene .native-grass {
  animation-name: overgrowth-grass-gust;
  animation-timing-function: steps(1, end);
}
@keyframes overgrowth-grass-gust {
  0%, 12%, 76%, 100% { background-position-x: 0; }
  22%, 41%, 64% { background-position-x: calc(-1 * var(--frame-width) * var(--native-pixel)); }
  30%, 52% { background-position-x: calc(-2 * var(--frame-width) * var(--native-pixel)); }
  88% { background-position-x: calc(-3 * var(--frame-width) * var(--native-pixel)); }
}
