/* Beach Buggy Racing (web) - loading screen and home screen.
   Sizes use --u, 1% of the height on wide screens and a little less on narrow ones,
   so the layout keeps the game's proportions at any window size. */

@font-face {                            /* the game's own lettering, made from its font by 9_web_assets.py */
  font-family: 'BBR Title';
  src: url(../assets/fonts/Title.ttf) format('truetype');
  font-display: block;
}

:root {
  --u: min(1vh, 0.75vw);
  --g: min(100vh / 720, 100vw / 1080);   /* one unit of the game's 1080 x 720 menu layout */
  --spare-x: max(0px, (100vw - 1080 * var(--g)) / 2);   /* beside the layout on wider screens */
  --spare-y: max(0px, (100vh - 720 * var(--g)) / 2);    /* above and below it on narrower ones */
  --ink: #111526;
  --white: #ffffff;
  --blue: #1b5fd6;
  --blue-deep: #0a2b86;
  --bounce: cubic-bezier(.34, 1.7, .5, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #0b3fae;
}

body {
  font-family: 'BBR Title', 'Trebuchet MS', sans-serif;
  color: var(--white);
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

#scene {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

[hidden] { display: none !important; }

/* White lettering with the game's thick dark outline */
.outlined {
  paint-order: stroke fill;
  -webkit-text-stroke: 0.16em var(--ink);
  text-shadow: 0 0.07em 0 var(--ink);
}

/* ---- loading screen -------------------------------------------------------------------- */

.loading {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #0050e0 url(../assets/ui/loading_background.png) center / cover no-repeat;
  transition: opacity .55s ease;
}

.loading::before {                       /* the darker edges of the game's loading screen */
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, transparent 45%, rgba(0, 8, 60, .55) 100%);
  pointer-events: none;
}

.loading.is-done { opacity: 0; }

.loading > * { position: relative; }

.loading__logo {
  width: calc(var(--u) * 150);
  max-width: 88vw;
  margin-top: calc(var(--u) * 4);
  filter: drop-shadow(0 calc(var(--u) * 1) calc(var(--u) * 1.5) rgba(0, 10, 60, .45));
}

.loading__bar {
  display: flex;
  align-items: center;
  width: calc(var(--u) * 140);
  max-width: 84vw;
  margin-top: calc(var(--u) * 3);
}

.loading__flag { height: calc(var(--u) * 8); flex: none; }
.loading__flag--start { transform: scaleX(-1); margin-right: calc(var(--u) * -1.2); }
.loading__flag--end { margin-left: calc(var(--u) * -1.2); }

.loading__track {
  flex: 1;
  height: calc(var(--u) * 2.4);
  border: calc(var(--u) * .45) solid #050d33;
  border-radius: 99px;
  background: #06236f;
  overflow: hidden;
}

.loading__fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(#6aa8ff, #2c69e0 60%, #2358c4);
  transition: width .3s ease-out;
}

.loading__text {
  margin: calc(var(--u) * 1.5) 0 0;
  font-size: calc(var(--u) * 7);
  line-height: 1;
}

/* the dots appear one after another, then start again */
.loading__dots i { font-style: normal; animation: dot1 1.6s steps(1) infinite; }
.loading__dots i:nth-child(2) { animation-name: dot2; }
.loading__dots i:nth-child(3) { animation-name: dot3; }

@keyframes dot1 { 0% { opacity: 0; } 25% { opacity: 1; } }
@keyframes dot2 { 0% { opacity: 0; } 50% { opacity: 1; } }
@keyframes dot3 { 0% { opacity: 0; } 75% { opacity: 1; } }

/* ---- screens and the game's layout ---------------------------------------------------------
   Menus are placed as the game places them (read from its Screens/*.json): at (--x, --y) in its
   1080 x 720 layout, which is scaled to fit; an element anchored to a side moves towards it by
   --ratio of the spare room there (the game's default ratio is 1). */

.screen {
  position: fixed;
  inset: 0;
  z-index: 10;
  pointer-events: none;
}
.screen.is-inactive * { pointer-events: none !important; }

.ui {
  position: absolute;
  left: calc(50vw + (var(--x) - 540) * var(--g) + var(--ax, 0) * var(--ratio-x, 1) * var(--spare-x));
  top: calc(50vh + (var(--y) - 360) * var(--g) + var(--ay, 0) * var(--ratio-y, 1) * var(--spare-y));
}
.anchor-left { --ax: -1; }
.anchor-right { --ax: 1; }
.anchor-top { --ay: -1; }
.anchor-bottom { --ay: 1; }

.home__logo {                            /* 800 x 350, centred on its position */
  width: calc(800 * var(--g));
  height: calc(350 * var(--g));
  translate: -50% -50%;
  filter: drop-shadow(0 calc(var(--u) * 1.2) calc(var(--u) * 1.6) rgba(0, 20, 60, .35));
  will-change: scale;                    /* pops in and out on the game's Boing transition */
}

/* A game button (VuGameButtonEntity). Its box is the touch rectangle; (--tx, --ty) is where the
   button's position lies inside it: the point its rectangles are measured from and that it
   scales about. Image, icon and label rectangles are the game's, in layout units. */
.game-button {
  --tx: 85; --ty: 75; --tw: 170; --th: 150;
  position: absolute;
  width: calc(var(--tw) * var(--g));
  height: calc(var(--th) * var(--g));
  margin: calc(var(--ty) * var(--g) * -1) 0 0 calc(var(--tx) * var(--g) * -1);
  transform-origin: calc(var(--tx) * var(--g)) calc(var(--ty) * var(--g));
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  pointer-events: auto;
  outline: none;
  -webkit-tap-highlight-color: transparent;
  will-change: translate, scale;
}

.game-button__image {
  position: absolute;
  inset: 0;
  background: var(--off) center / 100% 100% no-repeat;
  --shadow: drop-shadow(0 calc(var(--g) * 5) calc(var(--g) * 5) rgba(0, 0, 0, .35));
  filter: var(--shadow);
}
.flip-image-y .game-button__image { scale: 1 -1; }

.game-button__icon {                     /* default icon rectangle (-75, -75, 150, 150) */
  --ix: -75; --iy: -75; --iw: 150; --ih: 150;
  position: absolute;
  left: calc((var(--tx) + var(--ix)) * var(--g));
  top: calc((var(--ty) + var(--iy)) * var(--g));
  width: calc(var(--iw) * var(--g));
  height: calc(var(--ih) * var(--g));
  pointer-events: none;
}
.icon-help { --ix: -65; --iy: -65; --iw: 130; --ih: 130; }
.icon-lock { --ix: -55; --iy: -75; --iw: 120; --ih: 120; }

.game-button__label {                    /* font ButtonBelow: size 30, centred on (0, --label-y) */
  position: absolute;
  left: calc(var(--tx) * var(--g));
  top: calc((var(--ty) + var(--label-y, 80)) * var(--g));
  translate: -50% -50%;
  font-size: calc(30 * var(--g));
  line-height: 1;
  white-space: nowrap;
}

.square-button { --tx: 85; --ty: 75; --tw: 170; --th: 150; }
.play-button { --tx: 150; --ty: 90; --tw: 300; --th: 180; --label-y: 65; }
.play-button .game-button__icon { --ix: -100; --iy: -100; --iw: 220; --ih: 140; }
.play-button .game-button__label,
.wide-button .game-button__label { font-size: calc(45 * var(--g)); }   /* font Button */
.wide-button { --tx: 200; --ty: 48; --tw: 400; --th: 96; --label-y: 0; }
.back-button { --tx: 65; --ty: 55; --tw: 130; --th: 120; --label-y: 45; }
.back-button .game-button__image { left: calc(18 * var(--g)); top: calc(10 * var(--g)); width: calc(90 * var(--g)); height: calc(85 * var(--g)); }
.back-button .game-button__icon { --ix: -25; --iy: -21; --iw: 40; --ih: 40; scale: -1 1; }

.tex-square-a { --off: url(../assets/ui/button_square_a.png); --on: url(../assets/ui/button_square_a_selected.png); }
.tex-square-b { --off: url(../assets/ui/button_square_b.png); --on: url(../assets/ui/button_square_b_selected.png); }
.tex-play { --off: url(../assets/ui/button_play.png); --on: url(../assets/ui/button_play_selected.png); }
.tex-large { --off: url(../assets/ui/button_large.png); --on: url(../assets/ui/button_large_selected.png); }
.tex-small { --off: url(../assets/ui/button_small.png); --on: url(../assets/ui/button_small_selected.png); }

/* selected: the game's highlighted image, pulsing (the icon and label stay as they are) */
.game-button.is-selected .game-button__image {
  background-image: var(--on);
  animation: focus-pulse 1s ease-in-out infinite;
}

/* held down: 5% smaller, like the game's buttons (ConstantDB UI/PressedButtonSizeReduction) */
.game-button.is-pressed,
.message-box__button.is-pressed { transform: scale(.95); }

/* The game's focus pulse: a focused button's image breathes between white and (180, 180, 180)
   once a second (its UI manager's HighlightRate and colour, read from the game). */
@keyframes focus-pulse {
  50% { filter: var(--shadow,) brightness(.706); }
}

/* Settings: the two cars beside More Games pop out from the button's centre */
.settings__car {
  position: absolute;
  pointer-events: none;
  will-change: scale;
}
.settings__car--bunny {                  /* rect (-390, -90, 250, 180) */
  width: calc(250 * var(--g));
  height: calc(180 * var(--g));
  margin: calc(-90 * var(--g)) 0 0 calc(-390 * var(--g));
  transform-origin: calc(390 * var(--g)) calc(90 * var(--g));
}
.settings__car--roller {                 /* rect (130, -100, 270, 180) */
  width: calc(270 * var(--g));
  height: calc(180 * var(--g));
  margin: calc(-100 * var(--g)) 0 0 calc(130 * var(--g));
  transform-origin: calc(-130 * var(--g)) calc(100 * var(--g));
}

/* ---- Audio screen (the game's Screens/Audio) --------------------------------------------- */

.screen-darken {                         /* the game's UI/BackgroundDarken: black at 90/255, faded */
  position: absolute;
  inset: 0;
  background: rgb(0 0 0 / .353);
  will-change: opacity;
}

.tex-medium { --off: url(../assets/ui/button_medium.png); --on: url(../assets/ui/button_medium_selected.png); }
.standard-button { --tx: 125; --ty: 40; --tw: 250; --th: 80; --label-y: 0; }   /* rect (-125, -40, 250, 80) */

.button-font {                           /* font Button: size 45, white with a black outline */
  font-size: calc(45 * var(--g));
  paint-order: stroke fill;
  -webkit-text-stroke: .1em #000;
}

/* A volume slider (the game's VuSliderEntity): a 500 x 90 frame from its top-left corner, the
   name just above it and ten bars inside. The bars are cells of UI/Settings_Bar (24 x 68, 26
   apart; lit ones 67 lower) drawn at 35 x 60, 41 apart, from (50, 15). */
.volume-slider {
  position: absolute;
  width: calc(500 * var(--g));
  height: calc(90 * var(--g));
  pointer-events: auto;
  touch-action: none;
  cursor: pointer;
  outline: none;
}

.volume-slider__frame {
  position: absolute;
  inset: 0;
  background: url(../assets/ui/button_large.png) center / 100% 100% no-repeat;
  --shadow: drop-shadow(0 calc(var(--g) * 5) calc(var(--g) * 5) rgba(0, 0, 0, .35));
  filter: var(--shadow);
}
.volume-slider.is-selected .volume-slider__frame {
  background-image: url(../assets/ui/button_large_selected.png);
  animation: focus-pulse 1s ease-in-out infinite;
}

.volume-slider__label {                 /* its bottom on the frame's top edge (3 units up, measured) */
  position: absolute;
  left: 0;
  bottom: calc(100% + 3 * var(--g));
  width: 100%;
  text-align: center;
  line-height: 1;
  white-space: nowrap;
}

.volume-slider__bar {
  position: absolute;
  left: calc((50 + 41 * var(--i)) * var(--g));
  top: calc(15 * var(--g));
  width: calc(35 * var(--g));
  height: calc(60 * var(--g));
  background: url(../assets/ui/settings_bar.png) no-repeat;
  background-size: calc(256 * 35 / 24 * var(--g)) calc(256 * 60 / 68 * var(--g));
  background-position: calc(-26 * var(--i) * 35 / 24 * var(--g)) calc(-120 * 60 / 68 * var(--g));
}
.volume-slider__bar.is-on {
  background-position: calc(-26 * var(--i) * 35 / 24 * var(--g)) calc(-187 * 60 / 68 * var(--g));
}

/* controller prompt, only while a gamepad is in use */
.pad-hint {
  position: absolute;
  left: 50%;
  bottom: calc(var(--u) * 2.5);
  translate: -50% 0;
  margin: 0;
  display: none;
  align-items: center;
  gap: calc(var(--u) * 1.2);
  padding: calc(var(--u) * .8) calc(var(--u) * 2.2);
  border-radius: 99px;
  background: rgba(8, 22, 70, .55);
  font-size: calc(var(--u) * 3.4);
}
body[data-input='gamepad'] .home:not(.is-inactive) .pad-hint { display: flex; }

.pad-glyph {
  display: inline-grid;
  place-items: center;
  width: 1.35em;
  height: 1.35em;
  border-radius: 50%;
  font-size: .85em;
  color: #fff;
  -webkit-text-stroke: 0;
  text-shadow: none;
  box-shadow: inset 0 -.12em 0 rgba(0, 0, 0, .3);
}
.pad-glyph--a { background: #2fa84f; }
.pad-glyph--b { background: #d8413a; }

/* ---- message box -----------------------------------------------------------------------
   The game's MessageBox_SimpleA, in the game's own layout units: its menus are made for a
   1080 x 720 screen scaled to fit, and --g is one of those units. The panel is three slices
   of MessageBoxBack_small, the OK button is the game's standard button, and the screen
   behind is blurred. The pop in and out is the game's Boing transition (transition.js). */

.message-box {
  position: fixed;
  inset: 0;
  z-index: 20;
}

.message-box__blur {
  position: absolute;
  inset: 0;
  background: rgba(0, 12, 40, .12);
  -webkit-backdrop-filter: blur(calc(var(--g) * 8));
  backdrop-filter: blur(calc(var(--g) * 8));
  animation: fade-in .2s ease both;
}
.message-box.is-closing .message-box__blur { animation: fade-out .3s ease both; }

.message-box__window {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--g) * 680);
  height: calc(var(--g) * 350);
  margin: calc(var(--g) * -200) 0 0 calc(var(--g) * -340);   /* its centre is 10 units above the middle */
  transform-origin: calc(var(--g) * 340) calc(var(--g) * 190);   /* scales about its centre */
  will-change: scale;
}

.message-box__back {
  position: absolute;
  top: 0;
  height: 100%;
  background: url(../assets/ui/message_box.png) 0 0 / 100% 100% no-repeat;
}
.message-box__back--left { left: 0; width: calc(var(--g) * 140); }
.message-box__back--middle {                                   /* the image's right quarter, stretched */
  left: calc(var(--g) * 139);
  width: calc(var(--g) * 402);
  background-size: 400% 100%;
  background-position: 100% 0;
}
.message-box__back--right { right: 0; width: calc(var(--g) * 140); transform: scaleX(-1); }

.message-box__heading,
.message-box__body {
  position: absolute;
  display: grid;
  place-items: center;
  margin: 0;
  font-weight: normal;
  text-align: center;
  paint-order: stroke fill;
  -webkit-text-stroke: .1em rgba(20, 20, 20, .2);              /* the fonts' outline: (20, 20, 20) at 50/255 */
  text-shadow: 0 0 .04em rgba(20, 20, 20, .35);                /* softened, as the game draws it */
}
.message-box__heading {                                        /* font Dialog_Header */
  left: calc(var(--g) * 110);
  top: calc(var(--g) * 12);
  width: calc(var(--g) * 460);
  height: calc(var(--g) * 60);
  font-size: calc(var(--g) * 55);
  line-height: 1;
  white-space: nowrap;
}
.message-box__body {                                           /* font Medium */
  left: calc(var(--g) * 65);
  top: calc(var(--g) * 90);
  width: calc(var(--g) * 550);
  height: calc(var(--g) * 220);
  font-size: calc(var(--g) * 35);
  line-height: 1.25;
}

.message-box__button {                                         /* centred at (750, 530) of the layout */
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--g) * 250);
  height: calc(var(--g) * 96);
  margin: calc(var(--g) * 122) 0 0 calc(var(--g) * 85);
  padding: 0;
  border: 0;
  background: none;
  color: var(--white);
  font: inherit;
  font-size: calc(var(--g) * 45);
  paint-order: stroke fill;
  -webkit-text-stroke: .1em #000;                              /* font Button: black outline */
  cursor: pointer;
  outline: none;
  isolation: isolate;
  will-change: scale;
}
.message-box__button::before {                                 /* focused, mirrored as in the game */
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url(../assets/ui/button_medium_selected.png) center / 100% 100% no-repeat;
  transform: scaleX(-1);
  animation: focus-pulse 1s ease-in-out infinite;
}

@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }

.toast {
  position: fixed;
  left: 50%;
  top: calc(var(--u) * 3);
  z-index: 40;
  translate: -50% 0;
  margin: 0;
  padding: calc(var(--u) * 1) calc(var(--u) * 3);
  border-radius: 99px;
  background: rgba(8, 22, 70, .75);
  font-size: calc(var(--u) * 3.2);
  animation: toast 2.6s ease both;
}

@keyframes toast {
  0% { opacity: 0; transform: translateY(-120%); }
  12%, 85% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(-40%); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: .01s !important; }
}
