html,
body {
    margin: 0;
    padding: 0;
    height: 100%;
    color: rgba(255, 255, 255, 0.87);
    background-color: #000000;
    font-family: Arial, Helvetica, sans-serif;
    /* A phone must not rubber-band the page while a thumb is on the d-pad, and
       must not zoom on a double tap that was meant to be two slashes. */
    overscroll-behavior: none;
    -webkit-text-size-adjust: 100%;
}

#app {
    width: 100%;
    /* dvh, not vh: a mobile browser's URL bar makes vh taller than the visible
       screen, which pushes the bottom of the on-screen gamepad off it. */
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    display: flex;
    /* `safe` because a zoomed-in arena is deliberately larger than the page:
       plain centring would put half the overflow above and left of the
       scrollable origin, where no scroll can reach it. The plain value first is
       the fallback for browsers without safe alignment. */
    justify-content: center;
    justify-content: safe center;
    align-items: center;
    align-items: safe center;
}

/* Browser zoom has pinned the arena larger than the page (see
   `src/ui/fitArena.ts`). It becomes a scroll container, the way any zoomed page
   does — the only way to reach the part of the arena off screen. Never active
   at the fitted size, so normal play never grows a scrollbar. */
#app.is-zoomed {
    overflow: auto;
}

#game-container {
    /* Relative so the fight HUD can overlay the canvas rectangle: the HUD is
       inset:0 against this box, and its container units (1cqw = 8 logical px)
       are only honest if this box **is** the canvas rectangle. */
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;

    /* **The box is the largest 4:3 rectangle that fits the page.** The game is
       authored at 800x600 and never distorts, so the ratio is stated once and
       the height is the axis that runs out first on a normal window. `75vw` is
       the same constraint for a window taller than it is wide; `100%` is the
       page's own height.

       This rule is the first paint and the on-screen deck's layout. On a page
       without the deck `src/ui/fitArena.ts` pins the same box in CSS pixels,
       because a viewport-sized box would re-fit at every zoom level and leave
       Ctrl/Cmd +/- with nothing to change (see that file).

       **The cap is what keeps a big monitor sane.** 1200px is 2x the authored
       600; the arena stops growing there and the page shows background around
       it. */
    --arena-max-height: 1200px;
    height: min(100%, 75vw, var(--arena-max-height));
    width: auto;
    aspect-ratio: 4 / 3;
    /* Sized by the rule above, never stretched or squashed by the flex page.
       `safe` for the same reason `#app` uses it: at a zoomed-in size the box is
       larger than the window, and plain centring would hide the top of it above
       the scrollable origin. */
    flex: none;
    align-self: center;
    align-self: safe center;
}

#game-container canvas {
    display: block;
    /* Exactly the box, not "a size that happens to fit inside it": the HUD
       overlays this rectangle, and a canvas letterboxed in a larger box would
       put every HUD element off the arena. */
    width: 100%;
    height: 100%;
    touch-action: none;
}

.spritePosition {
    margin: 10px 0 0 10px;
    font-size: 0.8em;
}

.button {
    width: 140px;
    margin: 10px;
    padding: 10px;
    background-color: #000000;
    color: rgba(255, 255, 255, 0.87);
    border: 1px solid rgba(255, 255, 255, 0.87);
    cursor: pointer;
    transition: all 0.3s;

    &:hover {
        border: 1px solid #0ec3c9;
        color: #0ec3c9;
    }

    &:active {
        background-color: #0ec3c9;
    }

    /* Disabled styles */
    &:disabled {
        cursor: not-allowed;
        border: 1px solid rgba(255, 255, 255, 0.3);
        color: rgba(255, 255, 255, 0.3);
    }
}