/* The supplied landscape artwork stays 16:9. Portrait crops it uniformly. */
body{height:100dvh;min-height:0;overflow:hidden;padding:0}
.game-shell{width:min(100vw,calc(100dvh * 16 / 9));height:auto;max-width:none;min-height:0;aspect-ratio:16/9;margin:auto;background:none;overflow:hidden}
.viewport{position:absolute;inset:0;width:100%;height:100%;padding:0}
.scene{position:absolute;inset:0;width:100%;height:100%;aspect-ratio:16/9;margin:0;background-size:cover;background-position:center}
.playfield{inset:auto;transform:none}
#scene-brand{position:absolute;z-index:1;transform:translateX(-50%);object-fit:contain;pointer-events:none;filter:drop-shadow(0 3px 3px #0006)}
.cell{will-change:auto}
@media(max-aspect-ratio:1.04999){.game-shell{width:100vw;height:100dvh;aspect-ratio:auto}.scene{aspect-ratio:auto}}
/* Dialog artwork uses cover, which crops without stretching. */
dialog.bonus-intro,dialog.bonus-total{background-size:cover}

/* The multiplier travels with its amulet instead of floating above the card art. */
.bonus-card-art .bonus-charm{position:absolute;right:1%;bottom:4%;width:44%;height:50%;transform:rotate(12deg);display:grid;place-items:center}
.bonus-confirm .bonus-card-art .bonus-charm{right:0;bottom:0;width:45%;height:55%}
.bonus-card-art .bonus-charm .bonus-amulet{position:static;inset:auto;width:100%;height:100%;transform:none;object-fit:contain}
.bonus-card-art .bonus-charm .bonus-amulet-value{position:absolute;inset:0;width:100%;height:100%;transform:none;display:grid;place-items:center;font:calc(24 * var(--bonus-unit)) Gaia Rubik Bold,Arial;line-height:1;color:#ffe087;text-shadow:0 2px 2px #000;white-space:nowrap;pointer-events:none}

/* Branded loading covers unfinished render setup, then reveals the ready stage. */
.bonus-card-face{transition:border-color .16s ease-out,filter .16s ease-out}
.scene #loading{position:absolute;inset:0;left:0;bottom:0;z-index:30;transform:none;width:100%;height:100%;padding:24px;border-radius:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px;background:linear-gradient(#100c1ce8,#100b19ee);white-space:normal;text-align:center;opacity:1;transition:opacity .24s ease-out}
#loading>img{width:clamp(130px,22vmin,280px);height:auto;object-fit:contain;filter:drop-shadow(0 8px 12px #0008)}
#loading>p{margin:0;color:#f5dd99;font:clamp(10px,1.6vmin,16px)/1.4 Gaia Rubik,Arial;letter-spacing:1.5px}
.loading-track{width:clamp(150px,28vmin,320px);height:4px;border-radius:4px;overflow:hidden;background:#ffffff1a}
#loading-progress{display:block;width:0;height:100%;border-radius:inherit;background:linear-gradient(90deg,#ba8d49,#ffe7a0);transition:width .18s ease-out}
.scene #loading.leaving{opacity:0;pointer-events:none}
.console button,dialog button{touch-action:manipulation;-webkit-tap-highlight-color:transparent}
button:disabled:hover{filter:none}
@media(hover:hover) and (pointer:fine){.console button:hover{filter:brightness(1.12)}.bonus-card:focus-within .bonus-card-face,.bonus-card:hover .bonus-card-face{border-color:#ffffff55;filter:brightness(1.06)}}
@media(prefers-reduced-motion:reduce){.scene #loading,#loading-progress{transition:none}.console button,dialog button,.bonus-card-face{transition:none}}

.scene:not(.spine-ready):not(.static-ready) .playfield,.scene:not(.spine-ready):not(.static-ready) #mascot{visibility:hidden}
.scene[data-layout="portrait"] #mascot{display:none}

.scene:has(#loading:not([hidden])) #scene-brand{visibility:hidden}
.console{transition:opacity .2s ease-out}
.game-shell:has(#loading:not([hidden])) .console{opacity:0;visibility:hidden}
@media(prefers-reduced-motion:reduce){.console{transition:none}}

/* The backdrop fades with the screen, so exits reveal the board continuously. */
dialog.bonus-intro[data-phase="in"]::backdrop{animation:maia-backdrop-in var(--intro-enter) ease-out both}
dialog.bonus-intro[data-phase="out"]::backdrop{animation:maia-backdrop-out var(--intro-exit) ease-in forwards}
@keyframes maia-backdrop-in{from{background:#08040b00}to{background:#08040b}}
@keyframes maia-backdrop-out{from{background:#08040b}to{background:#08040b00}}
/* Keep the background covered while Total Win hands over to the return wipe. */
dialog.bonus-total.celebration-exiting{animation:none!important}
dialog.bonus-total.celebration-exiting::backdrop{animation:none!important}
.bonus-total.celebration-exiting .celebration-stage{animation:celebration-exit .36s ease-in forwards}
.bonus-total.celebration-exiting .celebration-copy{opacity:0;transition:opacity .18s ease-out}
.scene:has(#loading:not([hidden])) #symbol-effects{visibility:hidden}
@media(prefers-reduced-motion:reduce){dialog.bonus-intro::backdrop,.bonus-total.celebration-exiting .celebration-stage{animation:none!important}.bonus-total.celebration-exiting .celebration-copy{transition:none}}

/* Total Win and the return screen share one continuous opaque background. */
dialog.bonus-return[data-phase="in"],dialog.bonus-return[data-phase="hold"]{animation:none!important}
dialog.bonus-return[data-phase="in"]::backdrop{animation:none!important;background:#08040b}

/* A board refill is a tumble in the current spin; raven awards are visible at the counter. */
.console #free-spin-detail{position:absolute;left:calc(38 * var(--ref-unit));top:calc(38 * var(--ref-unit));font:calc(14 * var(--ref-unit))/1 Gaia Rubik,Arial;white-space:nowrap;color:#c8c8c8;pointer-events:none}
.console #free-spin-detail.awarded{color:#ffe087}
.console[data-variant="mobile"] #free-spin-detail{left:calc(36 * var(--ref-unit));top:calc(27 * var(--ref-unit));font-size:calc(12 * var(--ref-unit))}
