The Stand-Up · importable interrupt
Every twelve minutes, the level stops and URIEL stands up.
Not skippable. Not a penalty. Nothing is lost by stopping. This page is the working component and the integration harness — any level in PAIX imports the same file and inherits the rule.
12:00
until the next Stand-Up · counts play time only, pauses when the tab is hidden
What it does to the child's body
- EYES · 20 seconds. Look at the farthest thing in the room. Eyes were built for distance; a screen keeps them locked at arm's length.
- SPINE · 20 seconds. Stand, chin back over the shoulders, head over ribs over hips. This is the one that keeps the neck from setting in the forward curve.
- REACH · 20 seconds. Reach up, lean left, lean right. Opens the front of the chest so the shoulders do not stay rolled forward.
- A seated alternative is always one click away. A child who cannot stand — chair, cast, bad day — gets the same beat sitting down. That is an alternative, not a skip.
Import it
<script type="module">
import { StandUp } from '../standup/standup.js';
const standUp = StandUp.install({
asset: '../opening/assets/uriel.png',
onPause: () => level.pause(), // your level stops here
onResume: () => level.resume(), // and picks up exactly where it was
});
</script>
Classic script tag also works — the file exposes window.PaixStandUp. The component ships its own styles, needs no build step, makes no network call, and stores nothing but a millisecond count in localStorage on the device.
Options
| Option | Default | What it is |
|---|---|---|
intervalMs | 720000 | Play time between interrupts. Twelve minutes is canon; lower it for younger cohorts, never raise it. |
asset | ./assets/uriel.png | Path to the URIEL cutout from the level's own folder. |
onPause / onResume | null | Stop and restart the level. Also fired as DOM events. |
onStep | null | Called with each stretch step, for levels that want their own cue. |
steps | eyes / spine / reach | Override the stretch. Each step needs a seated alternative or it will not seat. |
persist | true | Device-local elapsed count. Set false to store nothing at all. |
countIdleAsPlay | false | Hidden tabs and blurred windows do not count as play. |
calm | false | Freezes all motion. prefers-reduced-motion does this automatically. |
Methods and events
| Call | Effect |
|---|---|
standUp.trigger() | Run it now — for teachers, harnesses and tests. |
standUp.remaining() | Milliseconds of play left before the next one. |
standUp.pause() / .start() | Hold and resume the play clock, e.g. across your own menus. |
standUp.reset() | Zero the clock. Levels should call this after their own long cutscene. |
document.addEventListener('paix:standup:start' | 'paix:standup:end', …) | For anything that is not the level itself — audio, telemetry-free logging, a village surface. |
What it refuses to do
- No skip button, no Escape key, no click-outside. The child cannot dismiss the body rule, and neither can the level.
- No penalty for the interruption. No streak breaks, no timer runs down, no progress is lost. The panel says so on screen.
- No network call, no account, no child data off the device. The only thing written is a millisecond count, and that can be turned off.
- No shame. URIEL does the stretch badly alongside the child, because he is off-balance. That is in the canon and it stays.