/* Dragon Roost UI (marfim, ouro, carmim; texto marrom-escuro; verde para confirmar). Every size comes from --u = 1% of the 16:9 stage height (set by src/render/view.js),
   never from the window width. HUD and dock are pinned to the real window corners (plus the safe area). */
@font-face {
  font-family: 'Fredoka';
  src: url(../assets/fonts/fredoka-latin-600.woff2) format('woff2');
  font-weight: 600;
  font-display: swap;
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215;
}
@font-face {
  font-family: 'Fredoka';
  src: url(../assets/fonts/fredoka-latin-ext-600.woff2) format('woff2');
  font-weight: 600;
  font-display: swap;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fredoka';
  src: url(../assets/fonts/fredoka-latin-700.woff2) format('woff2');
  font-weight: 700;
  font-display: swap;
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215;
}
@font-face {
  font-family: 'Fredoka';
  src: url(../assets/fonts/fredoka-latin-ext-700.woff2) format('woff2');
  font-weight: 700;
  font-display: swap;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --u: 4.5px;
  --ink: #3a2416;
  --cream: #fff4dc;
  --sl: env(safe-area-inset-left, 0px);
  --sr: env(safe-area-inset-right, 0px);
  --st: env(safe-area-inset-top, 0px);
  --sb: env(safe-area-inset-bottom, 0px);
  --font: 'Fredoka', 'Baloo 2', 'Arial Rounded MT Bold', system-ui, sans-serif;
}
* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}
html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #7d6bb5;
  color: var(--ink);
  font-family: var(--font);
  font-weight: 700;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  overscroll-behavior: none;
}
#game {
  position: fixed;
  left: 0;
  top: 0;
  display: block;
  touch-action: none;
}
#ui {
  position: fixed;
  inset: 0;
  pointer-events: none;
}
#ui .live {
  pointer-events: auto;
}
button {
  font-family: var(--font);
  font-weight: 700;
  color: var(--ink);
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
  touch-action: manipulation;
}
button:disabled {
  cursor: default;
}
/* Buttons sink under the finger and spring back with one small overshoot (JUICE 21). They never change size on their
   own: the ones that invite a tap get a light passing over their face (.shine), never a breathing scale.
   Entry animations on buttons must fill "backwards" only (a forwards fill would keep the transform and kill the press). */
:root {
  --press: 0.94;
  --press-sink: calc(var(--u) * 0.45);
  --press-in: 0.07s;
  --press-out: 0.24s;
  --press-spring: cubic-bezier(0.3, 1.9, 0.5, 1);
}
button {
  transition: transform var(--press-out) var(--press-spring);
}
button:active:not(:disabled) {
  transform: translateY(var(--press-sink)) scale(var(--press));
  transition: transform var(--press-in) ease-out;
}
.shine {
  position: absolute;
  inset: 10% 4% 14%;
  border-radius: 99px;
  overflow: hidden;
  pointer-events: none;
}
.shine::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 30%;
  background: linear-gradient(100deg, transparent 0 20%, rgba(255, 255, 255, 0.5) 50%, transparent 80% 100%);
  transform: translateX(-130%);
  animation: shine 3.6s ease-in-out infinite;
}
@keyframes shine {
  0%,
  60% {
    transform: translateX(-130%);
  }
  100% {
    transform: translateX(470%);
  }
}
img {
  -webkit-user-drag: none;
  user-select: none;
}

/* outlined text like the design: white or cream letters with a thick brown outline */
.ol {
  --o: calc(var(--u) * 0.42);
  color: #fff;
  text-shadow:
    calc(var(--o) * 1) 0 0 var(--ink),
    calc(var(--o) * 0.924) calc(var(--o) * 0.383) 0 var(--ink),
    calc(var(--o) * 0.707) calc(var(--o) * 0.707) 0 var(--ink),
    calc(var(--o) * 0.383) calc(var(--o) * 0.924) 0 var(--ink),
    0 calc(var(--o) * 1) 0 var(--ink),
    calc(var(--o) * -0.383) calc(var(--o) * 0.924) 0 var(--ink),
    calc(var(--o) * -0.707) calc(var(--o) * 0.707) 0 var(--ink),
    calc(var(--o) * -0.924) calc(var(--o) * 0.383) 0 var(--ink),
    calc(var(--o) * -1) 0 0 var(--ink),
    calc(var(--o) * -0.924) calc(var(--o) * -0.383) 0 var(--ink),
    calc(var(--o) * -0.707) calc(var(--o) * -0.707) 0 var(--ink),
    calc(var(--o) * -0.383) calc(var(--o) * -0.924) 0 var(--ink),
    0 calc(var(--o) * -1) 0 var(--ink),
    calc(var(--o) * 0.383) calc(var(--o) * -0.924) 0 var(--ink),
    calc(var(--o) * 0.707) calc(var(--o) * -0.707) 0 var(--ink),
    calc(var(--o) * 0.924) calc(var(--o) * -0.383) 0 var(--ink),
    0 calc(var(--u) * 0.9) 0 rgba(58, 36, 22, 0.35);
}
.ink {
  color: var(--ink);
  font-weight: 700;
}

/* Stretchable art WITHOUT slices (the sliced pictures left a hairline where the pieces met, worse while a button is
   pressed or at fractional sizes). Three ways, all with whole pictures at their real proportion:
   1) default (pills, buttons, plaques): ::before = the picture pinned left; from its middle on, the picture's flat centre
      column stretches over it up to the right end. ::after = the picture pinned right, only its cap, fading into that.
   2) winged ribbons (ends stick out of the band): the #boot .tap way, see ".wing" below.
   3) pieces as wide as their picture: the dock way (two whole pictures cross-fading in the middle).
   Per piece: --img, --ka (picture width / height), --kr (right cap / height) and --H (the element's height). */
.nine,
#rotate p {
  isolation: isolate;
  background: none !important;
  --img: url(../assets/ui/btn-pill.webp);
  --ka: 3.97;
  --kr: 0.5;
  --hitx: 0px;
  --hity: 0px;
}
.nine::before,
.nine::after,
#rotate p::before,
#rotate p::after {
  content: '';
  position: absolute;
  z-index: -1;
  pointer-events: none;
  background-repeat: no-repeat;
}
/* (--hitx/--hity: a transparent rim that only enlarges the touch area of small buttons on phones, see screens.css) */
.nine::before,
#rotate p::before {
  top: calc(var(--hity) * -1);
  bottom: calc(var(--hity) * -1);
  left: calc(var(--hitx) * -1);
  right: calc(var(--hitx) * -1);
  border: solid transparent;
  border-width: var(--hity) calc(var(--H) * var(--kr) * 0.9 + var(--hitx)) var(--hity) var(--hitx);
  padding-left: calc(var(--H) * var(--ka) / 2);
  background-image: var(--img), var(--img);
  background-size:
    2000% 100%,
    auto 100%;
  background-position:
    center,
    left center;
  background-origin: content-box, padding-box;
  background-clip: content-box, padding-box;
}
.nine::after,
#rotate p::after {
  top: 0;
  bottom: 0;
  right: 0;
  width: calc(var(--H) * var(--kr) * 1.4);
  background-image: var(--img);
  background-size: auto 100%;
  background-position: right center;
  -webkit-mask-image: linear-gradient(270deg, #000 71%, transparent);
  mask-image: linear-gradient(270deg, #000 71%, transparent);
}
/* 2) winged ribbons: the flat middle stretches inside the padding, the two ends are the whole picture with a mask */
.wing {
  --kr: 1.18;
  padding: 0 calc(var(--H) * var(--kr) * 0.9);
  background: var(--img) center / 2000% 100% no-repeat content-box !important;
}
.wing::before,
.wing::after {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: auto;
  border: 0;
  padding: 0;
  background: var(--img) left center / auto 100% no-repeat;
  -webkit-mask-image: linear-gradient(
    90deg,
    #000 calc(var(--H) * var(--kr)),
    transparent calc(var(--H) * var(--kr) * 1.4)
  );
  mask-image: linear-gradient(90deg, #000 calc(var(--H) * var(--kr)), transparent calc(var(--H) * var(--kr) * 1.4));
}
.wing::after {
  background-position: right center;
  -webkit-mask-image: linear-gradient(
    270deg,
    #000 calc(var(--H) * var(--kr)),
    transparent calc(var(--H) * var(--kr) * 1.4)
  );
  mask-image: linear-gradient(270deg, #000 calc(var(--H) * var(--kr)), transparent calc(var(--H) * var(--kr) * 1.4));
}
/* whole picture, drawn once (the box has the picture's proportion) */
.whole::before {
  inset: 0;
  border: 0;
  padding: 0;
  background: var(--img) center / 100% 100% no-repeat;
}
.whole::after {
  content: none;
}
/* art plates: the image is the background, the text sits on top */
.plate {
  position: absolute;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
}
/* HUD plates sit on the foliage with a small solid shadow */
#hud .plate {
  filter: drop-shadow(0 calc(var(--u) * 0.5) 0 rgba(90, 50, 20, 0.35));
}

/* ---------------------------------------------------------------- boot + rotate */
#boot {
  position: fixed;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 3vmin;
  background: #7d6bb5 url(../assets/env/bg1.webp) center / cover no-repeat;
  z-index: 50;
}
#boot img {
  width: min(51vw, 68vh);
}
#boot .bar {
  width: min(40vw, 50vh);
  height: 2.2vmin;
  border: 0.5vmin solid var(--ink);
  border-radius: 99px;
  background: #fff4dc;
  overflow: hidden;
}
#boot .bar i {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(180deg, #ffe58a 0%, #f5b62e 48%, #d98a12 100%);
  transition: width 0.2s;
}
/* rotate screen (portrait phones): logo, the rotating-phone illustration and the message on a cream pill */
#rotate {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 60;
  background:
    linear-gradient(rgba(90, 60, 140, 0), rgba(90, 60, 140, 0.3)),
    #7d6bb5 url(../assets/env/bg1.webp) center / cover no-repeat;
  place-content: center;
  justify-items: center;
  gap: 5vmin;
  text-align: center;
}
#rotate .logo {
  width: min(72vw, 340px);
  filter: drop-shadow(0 4px 0 rgba(58, 36, 22, 0.25));
}
#rotate .ph {
  width: min(80vw, 400px);
  animation: phbob 2.8s ease-in-out infinite;
}
#rotate p::after {
  width: auto;
  aspect-ratio: 0.322;
} /* the text may take 1 to 3 lines: the cap follows the real height */
#rotate p {
  position: relative;
  margin: 0 6vw;
  padding: 6.5vmin 9vmin;
  --img: url(../assets/ui/panel.webp);
  --ka: 1.37;
  --kr: 0.23;
  --H: calc(2.4em + 13vmin);
  filter: drop-shadow(0 6px 0 rgba(58, 36, 22, 0.3));
  color: var(--ink);
  font: 700 clamp(22px, 6.6vw, 34px) / 1.2 var(--font);
  text-wrap: balance;
}
@keyframes phbob {
  50% {
    transform: translateY(-3%) rotate(-3deg);
  }
}

@media (orientation: portrait) and (max-width: 1000px) {
  #rotate {
    display: grid;
  }
}

/* ---------------------------------------------------------------- top HUD */
#hud {
  position: absolute;
  inset: 0;
}
#hud[hidden],
#hud [hidden],
#ui [hidden] {
  display: none !important;
}
.hud-left {
  position: absolute;
  left: calc(var(--hx) + var(--sl) + var(--u) * 2.4);
  top: calc(var(--st) + var(--u) * 1.1);
}
.hud-right {
  position: absolute;
  right: calc(var(--hx) + var(--sr) + var(--u) * 1.8);
  top: calc(var(--st) + var(--u) * 0.5);
  display: flex;
  align-items: flex-start;
  gap: calc(var(--u) * 1.1);
}
#wave-chip {
  left: calc(var(--u) * 2.4);
  top: calc(var(--u) * 0.2);
  width: calc(var(--u) * 28);
  height: calc(var(--u) * 7);
  background-image: url(../assets/ui/wave-plate.webp);
  justify-content: center;
  font-size: max(12px, calc(var(--u) * 3.9));
  font-weight: 700;
}
#wave-chip span {
  margin-top: calc(var(--u) * -0.3);
}
#upnext {
  left: calc(var(--u) * 31.4);
  top: 0;
  width: auto;
  min-width: calc(var(--u) * 31);
  height: calc(var(--u) * 7);
  background-image: url(../assets/ui/upnext-pill.webp);
  padding: 0 calc(var(--u) * 2.2);
  gap: calc(var(--u) * 1);
  font-size: max(11px, calc(var(--u) * 3.2));
  white-space: nowrap;
}
#upnext .icons {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 0.8);
}
#upnext .icons img {
  height: calc(var(--u) * 5.4);
  width: auto;
}
#goal {
  left: 0;
  top: calc(var(--u) * 8.4);
  width: auto;
  min-width: calc(var(--u) * 39.3);
  max-width: calc(var(--u) * 80);
  height: calc(var(--u) * 6);
  background-image: url(../assets/ui/goal-pill.webp);
  padding: 0 calc(var(--u) * 1.5) 0 calc(var(--u) * 8.2);
  font-size: max(11px, calc(var(--u) * 3.1));
  white-space: nowrap;
}
#goal.pulse {
  animation: goalpop 0.5s;
}
@keyframes goalpop {
  40% {
    transform: scale(1.06);
  }
}
#goal {
  display: none !important;
} /* the goal pill is gone */
#coins {
  position: absolute;
  left: calc(50% + var(--u) * 7.3);
  top: calc(var(--st) + var(--u) * 1.4);
  width: auto;
  min-width: calc(var(--u) * 17.8);
  height: calc(var(--u) * 7);
  background-image: url(../assets/ui/coin-pill.webp);
  justify-content: center;
  padding-left: 40%;
  font-size: max(12px, calc(var(--u) * 4.1));
  letter-spacing: 0.1em;
}
#coins.bump {
  animation: coinbump 0.2s;
}
@keyframes coinbump {
  40% {
    transform: scale(1.06);
    filter: brightness(1.15);
  }
}
/* the last flying coin: bigger pop and a warm glint on the counter */
#coins.bigbump {
  animation: coinbig 0.45s cubic-bezier(0.2, 1.4, 0.4, 1);
}
@keyframes coinbig {
  30% {
    transform: scale(1.08);
    filter: brightness(1.3) drop-shadow(0 0 calc(var(--u) * 1.5) rgba(255, 214, 90, 0.9));
  }
}
.reduced #coins.bump,
.reduced #coins.bigbump {
  animation: none;
}
/* fence health: wooden capsule frame (image) with the fence badge on the left; the fill is a glossy, glowing bar */
#fence {
  position: relative;
  width: calc(var(--u) * 52);
  height: calc(var(--u) * 8.3);
}
#fence .track {
  position: absolute;
  left: calc(var(--u) * 7.85);
  right: calc(var(--u) * 1.55);
  top: calc(var(--u) * 2.4);
  bottom: calc(var(--u) * 2.3);
  border-radius: 99px;
  overflow: hidden;
}
#fence .fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  border-radius: 99px;
  background: linear-gradient(#c8ff8a, #7fdc3e 45%, #49ad22 100%);
  box-shadow:
    0 0 calc(var(--u) * 1.2) rgba(150, 255, 90, 0.75),
    inset 0 calc(var(--u) * -0.5) 0 rgba(30, 90, 10, 0.35);
  transition: width 0.35s cubic-bezier(0.2, 0.8, 0.3, 1);
}
#fence .fill::before {
  content: '';
  position: absolute;
  left: calc(var(--u) * 1);
  right: calc(var(--u) * 1);
  top: 14%;
  height: 28%;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.5);
}
#fence .fill::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 99px;
  background: linear-gradient(100deg, transparent 0 40%, rgba(255, 255, 255, 0.45) 50%, transparent 60% 100%) no-repeat;
  background-size: 40% 100%;
  animation: fencesheen 3.2s ease-in-out infinite;
}
@keyframes fencesheen {
  0%,
  55% {
    background-position: -60% 0;
  }
  100% {
    background-position: 160% 0;
  }
}
#fence .vine {
  display: none;
}
#fence .num {
  position: absolute;
  left: calc(var(--u) * 7.85 + (100% - var(--u) * 9.4) / 2);
  top: 50%;
  transform: translate(-50%, -52%);
  text-align: center;
  font-size: max(12px, calc(var(--u) * 3.4));
  letter-spacing: 0.04em;
  font-weight: 700;
  white-space: nowrap;
}
#fence.low .fill {
  background: linear-gradient(#ffe39a, #ffb23e 45%, #f08a1e 100%);
  box-shadow:
    0 0 calc(var(--u) * 1.2) rgba(255, 190, 80, 0.8),
    inset 0 calc(var(--u) * -0.5) 0 rgba(140, 60, 0, 0.3);
}

#fence.hit {
  animation: fencehit 0.3s;
}
@keyframes fencehit {
  25% {
    transform: translateX(calc(var(--u) * -0.5));
  }
  60% {
    transform: translateX(calc(var(--u) * 0.4));
  }
}
#btn-pause {
  position: relative;
  width: calc(var(--u) * 7.3);
  height: calc(var(--u) * 7.3);
  margin-top: calc(var(--u) * 0.5);
  background: url(../assets/ui/pause.webp) center / contain no-repeat;
}

/* boss strip (35.3% x 9% of the stage, portrait 6% x 9.6% on its left end; the name never runs under the portrait) */
#boss-strip {
  left: calc(var(--u) * 1.2);
  top: calc(var(--u) * 8.4);
  width: calc(var(--u) * 62.8);
  height: calc(var(--u) * 10.4);
  padding: 0 calc(var(--u) * 4) 0 calc(var(--u) * 14);
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  gap: calc(var(--u) * 0.6);
}
#boss-strip[hidden] {
  display: none;
}
#boss-strip .bcrown {
  position: absolute;
  left: calc(var(--u) * 3.6);
  top: calc(var(--u) * -3.4);
  width: calc(var(--u) * 5.6);
  transform: rotate(-12deg);
  filter: drop-shadow(0 calc(var(--u) * 0.3) 0 rgba(58, 36, 22, 0.45));
}
#boss-strip .bb i::after {
  content: '';
  position: absolute;
  left: 6%;
  right: 6%;
  top: 16%;
  height: 22%;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.55);
}
#boss-strip .bp {
  position: absolute;
  left: calc(var(--u) * 0.2);
  top: calc(var(--u) * -1.2);
  width: calc(var(--u) * 12.6);
  height: calc(var(--u) * 11.6);
  filter: drop-shadow(0 calc(var(--u) * 0.3) 0 rgba(58, 36, 22, 0.5));
  object-fit: contain;
}
#boss-strip .bn {
  display: block;
  margin-right: calc(var(--u) * 8);
  font-size: calc(var(--u) * 3.4);
  line-height: 1;
  white-space: nowrap;
}
#boss-strip .bb {
  position: relative;
  height: calc(var(--u) * 3);
  margin-right: calc(var(--u) * 8);
  border: calc(var(--u) * 0.45) solid var(--ink);
  border-radius: 99px;
  background: #3a2a20;
  overflow: hidden;
}
#boss-strip .bb i {
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(#ffe979, #f5a623);
  border-radius: 99px;
  transition: width 0.2s;
}
#boss-strip .bpct {
  position: absolute;
  right: calc(var(--u) * 3.4);
  bottom: calc(var(--u) * 1.5);
  font-size: calc(var(--u) * 4);
  line-height: 1;
}

/* ---------------------------------------------------------------- dock */

/* compost bin: appears over the dock while dragging */
#bin {
  position: absolute;
  left: 50%;
  bottom: calc(var(--sb) + var(--u) * 17);
  transform: translateX(-50%) scale(0.6);
  width: calc(var(--u) * 13);
  height: calc(var(--u) * 13);
  background: url(../assets/ui/ic-compost.webp) center / contain no-repeat;
  opacity: 0;
  transition:
    transform 0.15s,
    opacity 0.15s;
  pointer-events: none;
}
#bin.show {
  opacity: 1;
  transform: translateX(-50%) scale(1);
}
#bin.hot {
  transform: translateX(-50%) scale(1.18);
  filter: drop-shadow(0 0 calc(var(--u) * 1.5) #ffe066);
}
#drag-ghost {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 35;
  pointer-events: none;
  transform-origin: center;
  will-change: transform;
}
/* world change: two cloud banks close over the screen and open again (src/app/cloud-transition.js); it never takes a touch */
.cloud-wipe {
  position: fixed;
  inset: 0;
  z-index: 39;
  overflow: hidden;
  pointer-events: none;
}
.cloud-wipe i {
  position: absolute;
  top: -6%;
  bottom: -6%;
  width: 62%;
  background: var(--cloud) center / cover no-repeat;
  animation: cloud-l var(--ct) both;
  --e: 17vh;
  /* the inner edge is a row of cloud tufts (two columns of soft discs) in front of a straight body */
  --tuft-a: radial-gradient(circle closest-side, #000 78%, transparent 100%);
  --tuft-b: radial-gradient(circle closest-side, #000 74%, transparent 100%);
  --body: linear-gradient(90deg, #000 calc(100% - var(--e) * 0.86), transparent calc(100% - var(--e) * 0.74));
  -webkit-mask-image: var(--tuft-a), var(--tuft-b), var(--body);
  mask-image: var(--tuft-a), var(--tuft-b), var(--body);
  -webkit-mask-size:
    calc(var(--e) * 1.3) calc(var(--e) * 1.3),
    calc(var(--e) * 1.05) calc(var(--e) * 1.3),
    100% 100%;
  mask-size:
    calc(var(--e) * 1.3) calc(var(--e) * 1.3),
    calc(var(--e) * 1.05) calc(var(--e) * 1.3),
    100% 100%;
  -webkit-mask-position:
    right calc(var(--e) * 0.35) top 0px,
    right 0px top calc(var(--e) * 0.65),
    0 0;
  mask-position:
    right calc(var(--e) * 0.35) top 0px,
    right 0px top calc(var(--e) * 0.65),
    0 0;
  -webkit-mask-repeat: repeat-y, repeat-y, no-repeat;
  mask-repeat: repeat-y, repeat-y, no-repeat;
}
.cloud-wipe i:first-child {
  left: 0;
}
.cloud-wipe i:last-child {
  right: 0;
  animation-name: cloud-r;
}
/* closes fast, rests a breath, opens a little slower (the screen is fully covered for about a third of a second) */
@keyframes cloud-l {
  0% {
    transform: translateX(-104%);
    animation-timing-function: cubic-bezier(0.2, 0.7, 0.3, 1);
  }
  26% {
    transform: translateX(-2%);
    animation-timing-function: linear;
  }
  31% {
    transform: translateX(0);
    animation-timing-function: cubic-bezier(0.3, 0.1, 0.7, 0.6);
  }
  100% {
    transform: translateX(-104%);
  }
}
@keyframes cloud-r {
  0% {
    transform: translateX(104%) scaleX(-1);
    animation-timing-function: cubic-bezier(0.2, 0.7, 0.3, 1);
  }
  26% {
    transform: translateX(2%) scaleX(-1);
    animation-timing-function: linear;
  }
  31% {
    transform: translateX(0) scaleX(-1);
    animation-timing-function: cubic-bezier(0.3, 0.1, 0.7, 0.6);
  }
  100% {
    transform: translateX(104%) scaleX(-1);
  }
}
.reduced .cloud-wipe {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .cloud-wipe {
    display: none;
  }
}

/* toasts and banners */
#toast {
  position: absolute;
  left: 50%;
  top: calc(var(--st) + var(--u) * 17);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 1);
}
#toast div {
  position: relative;
  --H: calc(var(--u) * 6);
  height: var(--H);
  display: grid;
  place-items: center;
  padding: 0 calc(var(--u) * 5.6);
  font-size: calc(var(--u) * 3.2);
  font-weight: 700;
  white-space: nowrap;
  animation: toastin 0.25s;
}
@keyframes toastin {
  from {
    transform: translateY(calc(var(--u) * -2)) scale(0.85);
    opacity: 0;
  }
}
/* wave / world announcement: a winged ribbon and a parchment pill, centred on the battlefield (never over the roost) */
#banner {
  position: absolute;
  left: var(--stage-x);
  width: calc(var(--stage-w) * 0.62);
  top: calc(var(--stage-y) + var(--stage-h) * 0.3);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 0.6);
  opacity: 0;
  transform: translateY(calc(var(--u) * -2));
  transition:
    opacity 0.3s,
    transform 0.3s cubic-bezier(0.3, 1.5, 0.5, 1);
  pointer-events: none;
}
#banner.show {
  opacity: 1;
  transform: none;
}
.reduced #banner {
  transform: none;
  transition: opacity 0.3s;
}
#banner .b1 {
  position: relative;
  --img: url(../assets/ui/ribbon-win.webp);
  --H: calc(var(--u) * 12.5);
  height: var(--H);
  min-width: calc(var(--u) * 56);
  display: grid;
  place-items: center;
  font-size: calc(var(--u) * 4.5);
  font-weight: 700;
  white-space: nowrap;
}
/* the cloth is the lower 42-85% of the picture (wings rise above it): the text sits on the cloth's centre, not the picture's */
#banner .b1 span {
  margin-top: calc(var(--H) * 0.27);
}
#banner .b2 {
  position: relative;
  --H: calc(var(--u) * 6.4);
  height: var(--H);
  display: grid;
  place-items: center;
  padding: 0 calc(var(--u) * 6);
  font-size: calc(var(--u) * 3.4);
  font-weight: 700;
  white-space: nowrap;
}
#banner .b2[hidden] {
  display: none;
}

/* ---------------------------------------------------------------- title */
#title {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* soft plum vignette: title, mascot and Play stay the brightest things; static, never a flash */
#title::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 70% 75% at 42% 48%, rgba(58, 22, 48, 0) 50%, rgba(58, 22, 48, 0.42) 100%);
}
#title[hidden] {
  display: none;
}
#title .blur {
  display: none;
}
#title .scene {
  position: absolute;
  left: var(--stage-x);
  top: var(--stage-y);
  width: var(--stage-w);
  height: var(--stage-h);
}
#title .logo {
  position: absolute;
  left: calc(var(--u) * 19.9);
  top: 1.6%;
  width: 37.4%;
}
#title .hazel {
  position: absolute;
  left: calc(var(--vw) / 2 + var(--u) * 6.2 - var(--stage-x));
  top: 21.3%;
  height: 59.5%;
  transform-origin: 50% 100%;
  animation: hazelidle 3s ease-in-out infinite;
}
@keyframes hazelidle {
  50% {
    transform: rotate(-1.2deg) scaleY(1.015);
  }
}
#title .play {
  position: absolute;
  left: calc(var(--u) * 28.6);
  top: 45.2%;
  width: 27.2%;
  height: 18.1%;
  padding-bottom: calc(var(--u) * 2.4);
  background: url(../assets/ui/btn-play.webp) center / 100% 100%;
  display: grid;
  place-items: center;
  font-size: calc(var(--u) * 9.5);
  font-weight: 700;
}
#title .play span {
  position: relative;
  z-index: 1;
}
#title .play {
  background: none;
  isolation: isolate;
}
#title .play::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: url(../assets/ui/btn-play.webp) center / 100% 100% no-repeat;
}
#title .cont {
  position: absolute;
  left: calc(var(--u) * 29.5);
  top: 65.6%;
  width: 26.6%;
  height: 7.7%;
  display: grid;
  place-items: center;
  font-size: calc(var(--u) * 3.8);
  font-weight: 700;
}
#title .cont[hidden] {
  display: none;
}
#title .rb {
  position: absolute;
  top: 75.5%;
  width: 9.9%;
  height: 19.7%;
}
/* Continue reads as a real button: a play badge on the left and a warm rim glow */
#title .cont .art::before {
  content: '';
  position: absolute;
  left: calc(var(--u) * 5.3);
  top: 50%;
  width: calc(var(--u) * 3.8);
  height: calc(var(--u) * 3.8);
  transform: translateY(-50%);
  background: url(../assets/ui/ic2-play.webp) center / contain no-repeat;
}
#title .cont .art {
  padding-left: calc(var(--u) * 9.3);
  padding-right: calc(var(--u) * 5.4);
  white-space: nowrap;
  overflow: hidden;
  box-shadow:
    0 0 0 calc(var(--u) * 0.35) rgba(232, 163, 61, 0.9),
    0 0 calc(var(--u) * 2) rgba(255, 210, 110, 0.55);
  border-radius: 99px;
}
/* secondary buttons get weight: a soft ground shadow */
#title .cont,
#title .rb {
  filter: drop-shadow(0 calc(var(--u) * 0.7) calc(var(--u) * 0.5) rgba(58, 36, 22, 0.4));
}
#title .rb .sq {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  margin: 0 auto;
  height: 76%;
  aspect-ratio: 1;
  background: url(../assets/ui/btn-medal.webp) center / 100% 100%;
  display: grid;
  place-items: center;
}
#title .rb .sq img {
  width: 66%;
  margin-top: -12%;
}
#title .rb .tag {
  position: absolute;
  left: -2%;
  right: -2%;
  bottom: 0;
  height: 30%;
  background: url(../assets/ui/tag-cream.webp) center / 100% 100%;
  display: grid;
  place-items: center;
  font-size: calc(var(--u) * 3.5);
  font-weight: 700;
}
#title .rb.r1 {
  left: calc(var(--u) * 24);
}
#title .rb.r2 {
  left: calc(var(--u) * 43.6);
}
#title .rb.r3 {
  left: calc(var(--u) * 63.7);
}
#title .tcoins {
  position: absolute;
  right: calc(var(--hx) + var(--sr) + var(--u) * 29.9);
  top: calc(var(--st) + var(--u) * 5.8);
  width: calc(var(--u) * 27.7);
  height: calc(var(--u) * 8.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 38%;
  font-size: calc(var(--u) * 5.2);
  font-weight: 700;
}
#title .gear {
  position: absolute;
  right: calc(var(--hx) + var(--sr) + var(--u) * 4.4);
  top: calc(var(--st) + var(--u) * 3);
  width: calc(var(--u) * 12.8);
  height: calc(var(--u) * 12.8);
  background: url(../assets/ui/btn-gear.webp) center / contain no-repeat;
}

/* less motion */
.reduced *,
.reduced *::before,
.reduced *::after {
  animation: none !important;
  transition: none !important;
}
/* paused (pause menu, Aerie, defeat): the HUD behind the panel holds still like the field (main.js sets .paused on <html>) */
.paused #hud *,
.paused #hud *::before,
.paused #hud *::after,
.paused #tut * {
  animation-play-state: paused !important;
}

/* ---------------------------------------------------------------- stretchable art, per piece (see .nine at the top) */
#upnext {
  --img: url(../assets/ui/upnext-pill.webp);
  --ka: 5.256;
  --H: calc(var(--u) * 7);
}
/* coin counters: the coin end is the left of the picture (it sticks out of the pill), the plain end is the right cap */
#coins,
#title .tcoins,
.shedcoins {
  --img: url(../assets/ui/coin-pill.webp);
  --ka: 2.349;
  --kr: 0.45;
}
/* the number keeps clear of the coin's rim and is a little smaller */
#coins {
  --H: calc(var(--u) * 7);
  padding-left: calc(var(--u) * 8.5) !important;
  padding-right: calc(var(--u) * 2.6) !important;
  font-size: max(12px, calc(var(--u) * 3.6));
  letter-spacing: 0.06em;
}
#title .tcoins {
  --H: calc(var(--u) * 8.5);
  padding: 0 calc(var(--u) * 4.3) 0 calc(var(--u) * 8.56);
  width: calc(var(--u) * 27.7);
  justify-content: center;
}
/* Continuous artwork prevents seams when the dock buttons are pressed and scaled. */
#dock .nine::before {
  inset: 0;
  border: 0;
  padding: 0;
  background-position: center;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-origin: padding-box;
  background-clip: border-box;
}
#btn-speed::after {
  content: none;
}
#btn-plant::before {
  background-image: url(../assets/ui/btn-gold.webp);
}
#btn-bees::before,
#btn-fert::before,
#btn-shed::before {
  background-image: url(../assets/ui/btn-cream.webp);
}
#btn-call::before {
  background-image: url(../assets/ui/btn-orange.webp);
}
#btn-speed::before {
  background-image: url(../assets/ui/btn-square.webp);
}
/* Play: one stretched picture */

/* bigger touch targets without changing the drawing */

/* ---------------------------------------------------------------- tutorial */
#tut {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
#tut[hidden] {
  display: none;
}
#tut .bubble {
  position: absolute;
  left: calc(50% - var(--u) * 43.6);
  top: calc(var(--stage-y) + var(--stage-h) * 0.351);
  width: calc(var(--u) * 64.9);
  height: calc(var(--u) * 26.4);
  background: url(../assets/ui/speech-bubble.webp) center / 100% 100% no-repeat;
  display: block;
  transition: top 0.3s;
}
#tut.low .bubble {
  top: calc(var(--stage-y) + var(--stage-h) * 0.52);
}
#tut .bust {
  position: absolute;
  left: calc(var(--u) * -1.5);
  top: calc(var(--u) * -1);
  height: calc(var(--u) * 24.5);
}
/* the text sits in the middle of the room the mascot leaves (22u to 60.4u), balanced lines, the skip link centred under it */
#tut .txt {
  position: absolute;
  left: calc(var(--u) * 22);
  right: calc(var(--u) * 4.5);
  top: calc(var(--u) * 8.9);
  transform: translateY(-50%);
  max-height: calc(var(--u) * 12.8);
  margin: 0;
  font-size: calc(var(--u) * 3.9);
  line-height: 1.2;
  font-weight: 600;
  text-align: center;
  text-wrap: balance;
}
#tut .txt b {
  font-weight: 700;
}
#tut .skip {
  position: absolute;
  left: calc(var(--u) * 41.2);
  transform: translateX(-50%);
  top: calc(var(--u) * 17);
  font-size: calc(var(--u) * 3.1);
  text-decoration: underline;
  white-space: nowrap;
  pointer-events: auto;
}
#tut .skip::before {
  content: '';
  position: absolute;
  inset: calc(var(--u) * -2) calc(var(--u) * -2);
}
#tut .hand {
  position: absolute;
  left: 0;
  top: 0;
  height: calc(var(--u) * 12.2);
  margin-left: calc(var(--u) * -2);
  margin-top: calc(var(--u) * -1);
  filter: drop-shadow(0 calc(var(--u) * 0.5) 0 rgba(58, 36, 22, 0.35));
}
#tut .arrow {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
#tut .arrow path {
  fill: none;
  stroke-linecap: round;
}
#tut .arrow .o {
  stroke: #3a2416;
  stroke-width: calc(var(--u) * 1.6);
  stroke-dasharray: calc(var(--u) * 2.4) calc(var(--u) * 1.6);
}
#tut .arrow .i {
  stroke: #fff4dc;
  stroke-width: calc(var(--u) * 0.8);
  stroke-dasharray: calc(var(--u) * 2.4) calc(var(--u) * 1.6);
}
#tut .arrow .ho {
  stroke: #3a2416;
  stroke-width: calc(var(--u) * 1.6);
  stroke-linejoin: round;
}
#tut .arrow .hi {
  stroke: #fff4dc;
  stroke-width: calc(var(--u) * 0.8);
  stroke-linejoin: round;
}
/* merge preview bubble: cream disc, golden glow ring, pointer towards the target, next-level plant and badge */
/* merge preview: the bubble art (assets/ui/prev-bubble.webp, pointer down); flipped when the bubble sits under the target */
#tut .prev {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(var(--u) * 15.5);
  height: calc(var(--u) * 15.5);
  margin: calc(var(--u) * -7.75) 0 0 calc(var(--u) * -7.75);
  isolation: isolate;
  animation: prevbob 1.4s ease-in-out infinite;
}
#tut .prev::before {
  content: '';
  position: absolute;
  left: -5%;
  top: -6%;
  width: 110%;
  height: 124%;
  z-index: -1;
  background: url(../assets/ui/prev-bubble.webp) center / 100% 100% no-repeat;
}
#tut .prev:not(.up)::before {
  top: -18%;
  transform: scaleY(-1);
}
#tut .prev .pp {
  position: absolute;
  left: 4%;
  top: 0;
  width: 92%;
  height: 92%;
  object-fit: contain;
}
#tut .prev .pb {
  position: absolute;
  right: calc(var(--u) * -0.6);
  bottom: calc(var(--u) * -0.2);
  width: calc(var(--u) * 6);
  height: calc(var(--u) * 6);
  background: url(../assets/ui/ic-badge.webp) center / contain no-repeat;
  display: grid;
  place-items: center;
  font-size: calc(var(--u) * 3.2);
}
#tut .prev .ps {
  position: absolute;
  height: calc(var(--u) * 4);
}
#tut .prev .ps.l {
  left: calc(var(--u) * -4);
  top: calc(var(--u) * 3);
}
#tut .prev .ps.r {
  right: calc(var(--u) * -4);
  top: calc(var(--u) * -1);
}
@keyframes prevbob {
  50% {
    margin-top: calc(var(--u) * -8.4);
  }
}

/* touch: the button is a bigger transparent hit area, the art inside keeps the design size */
#btn-pause {
  width: calc(var(--u) * 10.5);
  height: calc(var(--u) * 10.5);
  margin: calc(var(--u) * -0.5) calc(var(--u) * -1.6) 0 0;
  background: none;
  display: grid;
  place-items: center;
}
/* on small phones the button is under 44 px: the touch area grows around it (no layout change) */
#btn-pause::after {
  content: '';
  position: absolute;
  inset: min(0px, calc((var(--u) * 10.5 - 44px) / 2));
}
#btn-pause .art {
  width: calc(var(--u) * 7.3);
  height: calc(var(--u) * 7.3);
  background: url(../assets/ui/pause.webp) center / contain no-repeat;
}
/* Continue: the button is a taller touch area; the pill art (7.7u tall) is drawn in its middle */
#title .cont {
  height: 11.5%;
  top: 63.7%;
  --H: calc(var(--u) * 7.7);
}
#title .cont::before,
#title .cont::after {
  top: calc(50% - var(--H) / 2);
  bottom: calc(50% - var(--H) / 2);
}
#title .cont .art {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: var(--H);
  transform: translateY(-50%);
  display: grid;
  place-items: center;
}
#tut .skip {
  padding: calc(var(--u) * 3.2) calc(var(--u) * 2);
  margin: calc(var(--u) * -3.2) calc(var(--u) * -2);
}

/* little yellow shine accents, twinkling softly */
.spk {
  position: absolute;
  pointer-events: none;
  animation: twinkle 1.6s ease-in-out infinite;
  transform-origin: 50% 100%;
}
@keyframes twinkle {
  50% {
    scale: 1.12;
    opacity: 0.85;
  }
}
#title .sp-play-l {
  left: calc(var(--u) * 22.9);
  top: 44.6%;
  height: 6.4%;
}
#title .sp-play-r {
  left: calc(var(--u) * 77.2);
  top: 45.2%;
  height: 6.4%;
}
#title .sp-hazel {
  left: calc(var(--vw) / 2 + var(--u) * 6.2 - var(--stage-x));
  top: 17%;
  height: 8.5%;
}
#title .sp-snail {
  left: 51.4%;
  top: 68.5%;
  height: 4.3%;
  animation-delay: 0.5s;
}
#title .sp-coin {
  right: calc(var(--hx) + var(--sr) + var(--u) * 54.4);
  top: calc(var(--st) + var(--u) * 1.1);
  height: calc(var(--u) * 4.8);
  animation-delay: 0.3s;
}
#tut .sp-tut {
  left: calc(var(--u) * -1);
  top: calc(var(--u) * -2.6);
  height: calc(var(--u) * 5.8);
}

/* ---------------------------------------------------------------- dock: one grid for every button
   Fixed icon box + a text column centred in the remaining space; same height and the same gap everywhere.
   The main group is one row pinned left; speed is pinned right. Labels shrink (fitText) before touching an edge. */
/* one row inside the HUD box (2.4x the height at most): the same gap between every button, speed last; on very wide
   windows the row stops growing (the gaps would turn into holes) and stays pinned left like the top bar */
#dock {
  position: absolute;
  left: calc(var(--hx) + var(--sl) + var(--u) * 2);
  bottom: calc(var(--sb) + var(--u) * 2.2);
  width: min(calc(var(--vw) - var(--hx) * 2 - var(--sl) - var(--sr) - var(--u) * 4), calc(var(--u) * 182));
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  column-gap: calc(var(--u) * 1.3);
}
.dbtn {
  position: relative;
  height: calc(var(--u) * 12.8);
  width: calc(var(--u) * 30);
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 0.8);
  padding: 0 calc(var(--u) * 1.6) 0 calc(var(--u) * 1.2);
}
.dbtn .dic {
  flex: 0 0 calc(var(--u) * 9.6);
  height: calc(var(--u) * 9.6);
  display: grid;
  place-items: center;
}
.dbtn .dic img {
  max-width: 100%;
  max-height: 100%;
}
.dbtn .dtx {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 0.5);
  text-align: center;
}
.dbtn .lbl {
  display: block;
  max-width: 100%;
  font-size: max(11px, calc(var(--u) * 3.3));
  line-height: 1.04;
  font-weight: 700;
}
.dbtn .state {
  height: calc(var(--u) * 3.3);
  max-width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.dbtn .state:empty {
  display: none;
}
.dbtn .lock {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 0.4);
  font-size: max(10.5px, calc(var(--u) * 2.4));
  font-weight: 700;
  color: #6b4a2f;
  white-space: nowrap;
}
.dbtn .lock img {
  height: calc(var(--u) * 2.7);
}
.dbtn .ready {
  position: relative;
  --img: url(../assets/ui/pill-green.webp);
  --ka: 2.346;
  --H: calc(var(--u) * 3.3);
  padding: 0 calc(var(--u) * 2.05);
  height: var(--H);
  display: grid;
  place-items: center;
  font-size: max(10px, calc(var(--u) * 2.3));
  font-weight: 700;
  color: #fff;
}
.dbtn.locked .dic img {
  filter: grayscale(0.85) brightness(1.05);
  opacity: 0.6;
}
.dbtn.locked .lbl {
  opacity: 0.65;
}
#btn-plant {
  width: calc(var(--u) * 41.6);
  padding-left: calc(var(--u) * 1.6);
}
/* level tag sits on top of the button like a tab, so the icon and the text get the whole button */
#btn-plant .lvl {
  position: absolute;
  left: calc(var(--u) * 2.4);
  top: calc(var(--u) * -3.8);
  z-index: 2;
  --img: url(../assets/ui/pill-cream.webp);
  --ka: 1.886;
  --H: calc(var(--u) * 5.5);
  height: var(--H);
  padding: 0 calc(var(--u) * 2.8);
  display: grid;
  place-items: center;
  font-size: calc(var(--u) * 3.3);
  font-weight: 700;
}
#btn-plant .dic {
  flex-basis: calc(var(--u) * 10.6);
  height: calc(var(--u) * 12);
}
#btn-plant .lbl {
  font-size: calc(var(--u) * 4);
}
#btn-plant .price {
  position: relative;
  --img: url(../assets/ui/pill-cream.webp);
  --ka: 1.886;
  --H: calc(var(--u) * 4.8);
  height: var(--H);
  min-width: calc(var(--u) * 11);
  padding: 0 calc(var(--u) * 2.8) 0 calc(var(--u) * 2.4);
  gap: calc(var(--u) * 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: calc(var(--u) * 3.4);
  font-weight: 700;
}
#btn-plant .price img {
  flex: 0 0 auto;
  height: calc(var(--u) * 4.6);
  margin-left: calc(var(--u) * -1.8);
}
#btn-plant.poor .price {
  color: #a8322e;
}
#btn-plant.shake {
  animation: shake 0.3s;
}
@keyframes shake {
  25% {
    transform: translateX(calc(var(--u) * -0.8));
  }
  50% {
    transform: translateX(calc(var(--u) * 0.8));
  }
  75% {
    transform: translateX(calc(var(--u) * -0.4));
  }
}
#btn-fert .ring {
  flex: 0 0 calc(var(--u) * 9);
  height: calc(var(--u) * 9);
  position: relative;
  border-radius: 50%;
  background: conic-gradient(#f0a81e var(--p, 0%), #ecdcb8 0);
  display: grid;
  place-items: center;
}
#btn-fert .ring::before {
  content: '';
  position: absolute;
  inset: calc(var(--u) * 1.1);
  border-radius: 50%;
  background: #fff4dc;
  border: calc(var(--u) * 0.35) solid var(--ink);
}
#btn-fert .ring span {
  position: relative;
  font-size: calc(var(--u) * 2.9);
  font-weight: 700;
}
#btn-fert .ring[hidden] {
  display: none;
}
#btn-fert.active {
  animation: glowpulse 0.8s infinite alternate;
}
@keyframes glowpulse {
  to {
    filter: drop-shadow(0 0 calc(var(--u) * 1.2) #ffe066);
  }
}
#btn-call[hidden] {
  display: none;
}
#btn-call .t {
  font-size: calc(var(--u) * 4);
  font-weight: 700;
  line-height: 1;
}
#btn-call .lbl {
  font-size: calc(var(--u) * 3);
  white-space: nowrap;
}
#btn-call.start .t {
  display: none;
}
#btn-call.start .lbl {
  font-size: calc(var(--u) * 3.4);
}
#btn-speed {
  position: relative;
  flex: 0 0 auto;
  width: calc(var(--u) * 18.7);
  height: calc(var(--u) * 12.8);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--u) * 1);
  font-size: calc(var(--u) * 5);
  font-weight: 700;
}
#btn-speed img {
  height: calc(var(--u) * 4.4);
}
/* with the Call Wave button the row tightens so it never reaches the speed button */
#hud.calling #btn-plant {
  width: calc(var(--u) * 38);
}
#hud.calling .dbtn:not(#btn-plant) {
  width: calc(var(--u) * 26.5);
}
#hud.calling #btn-speed {
  width: calc(var(--u) * 17.3);
}
#hud.calling .dbtn .lbl {
  font-size: max(11px, calc(var(--u) * 3));
}
#hud.calling .dbtn .dic {
  flex-basis: calc(var(--u) * 8.4);
  height: calc(var(--u) * 8.4);
}
#hud.calling #btn-plant .dic {
  flex-basis: calc(var(--u) * 9.4);
  height: calc(var(--u) * 11);
}
/* 6-button dock (Call Wave showing): the cooldown ring sits on the sack icon as a badge, the label keeps its room (QA 08/11) */
#hud.calling #btn-fert .ring {
  position: absolute;
  left: calc(var(--u) * 1.4);
  bottom: calc(var(--u) * 0.4);
  width: calc(var(--u) * 5.8);
  height: calc(var(--u) * 5.8);
  z-index: 2;
}
#hud.calling #btn-fert .ring span {
  font-size: calc(var(--u) * 2);
}

/* small outlined labels: outline only, no drop shadow (it read as a ghost line) */
#btn-call .lbl,
#btn-call .t,
.dbtn .ready {
  --o: calc(var(--u) * 0.32);
  text-shadow:
    calc(var(--o) * 1) 0 0 var(--ink),
    calc(var(--o) * 0.924) calc(var(--o) * 0.383) 0 var(--ink),
    calc(var(--o) * 0.707) calc(var(--o) * 0.707) 0 var(--ink),
    calc(var(--o) * 0.383) calc(var(--o) * 0.924) 0 var(--ink),
    0 calc(var(--o) * 1) 0 var(--ink),
    calc(var(--o) * -0.383) calc(var(--o) * 0.924) 0 var(--ink),
    calc(var(--o) * -0.707) calc(var(--o) * 0.707) 0 var(--ink),
    calc(var(--o) * -0.924) calc(var(--o) * 0.383) 0 var(--ink),
    calc(var(--o) * -1) 0 0 var(--ink),
    calc(var(--o) * -0.924) calc(var(--o) * -0.383) 0 var(--ink),
    calc(var(--o) * -0.707) calc(var(--o) * -0.707) 0 var(--ink),
    calc(var(--o) * -0.383) calc(var(--o) * -0.924) 0 var(--ink),
    0 calc(var(--o) * -1) 0 var(--ink),
    calc(var(--o) * 0.383) calc(var(--o) * -0.924) 0 var(--ink),
    calc(var(--o) * 0.707) calc(var(--o) * -0.707) 0 var(--ink),
    calc(var(--o) * 0.924) calc(var(--o) * -0.383) 0 var(--ink);
}
#btn-fert {
  width: calc(var(--u) * 37);
}
#hud.calling #btn-fert {
  width: calc(var(--u) * 26.5);
}

/* phones lying down: taller dock buttons and bigger labels (touch >= 44 px); the dock only covers the bottom flower bed,
   so the field keeps its height */
@media (orientation: landscape) and (max-height: 500px) {
  #dock {
    width: calc(var(--vw) - var(--hx) * 2 - var(--sl) - var(--sr) - var(--u) * 4);
  }
  #dock .dbtn {
    flex: 1 1 auto;
  }
  .dbtn,
  #btn-speed {
    height: calc(var(--u) * 14);
  }
  .dbtn .lbl {
    font-size: max(12.5px, calc(var(--u) * 3.5));
  }
  #btn-plant .lbl,
  #btn-call .t {
    font-size: max(13.5px, calc(var(--u) * 4.2));
  }
  #hud.calling .dbtn .lbl {
    font-size: max(12px, calc(var(--u) * 3.2));
  }
  .dbtn .lock,
  .dbtn .ready {
    font-size: max(11px, calc(var(--u) * 2.6));
  }
  .dbtn .ready {
    --H: calc(var(--u) * 3.8);
  }
  #btn-speed {
    font-size: calc(var(--u) * 5.4);
  }
}

/* new plant card (merge discovery): ribbon + portrait + name; pops in with a small overshoot, rises away */
#disc {
  position: fixed;
  left: 50%;
  top: 30%;
  transform: translate(-50%, -100%) scale(0.82);
  transform-origin: 50% 100%;
  z-index: 4;
  pointer-events: none;
}
#disc.side {
  transform: translate(-50%, -50%) scale(1.3);
  transform-origin: 50% 50%;
}
#disc .rb.nine.wing {
  padding: 0 calc(var(--u) * 14) !important;
} /* the text keeps clear of the ribbon's golden posts in every language */
#disc .card {
  position: relative;
}
#disc .in {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: discin 0.26s both;
}
#disc .rb {
  animation: discrib 0.3s 0.08s backwards;
}
#disc .pl {
  animation: discpop 0.3s 0.16s backwards;
}
#disc.out .in {
  animation: discout 0.15s ease-in forwards;
}
#disc .rb {
  position: relative;
  z-index: 1;
  height: calc(var(--u) * 7.6);
  min-width: calc(var(--u) * 34);
  padding: 0 calc(var(--u) * 11.5);
  display: grid;
  place-items: center;
}
#disc .rb span {
  font-size: calc(var(--u) * 4.2);
  white-space: nowrap;
  margin-top: calc(var(--u) * -0.3);
}
#disc .card {
  margin-top: calc(var(--u) * -1.6);
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1.4);
  padding: calc(var(--u) * 2.2) calc(var(--u) * 2.8) calc(var(--u) * 1.2) calc(var(--u) * 1.6);
  filter: drop-shadow(0 0 calc(var(--u) * 1.5) rgba(255, 220, 110, 0.8));
}
/* the card and the level pill are painted art, not CSS boxes: the frame picture at the card's height */
#disc .card {
  --img: url(../assets/ui/btn-round.webp);
  --ka: 1.027;
  --kr: 0.31;
  --H: calc(var(--u) * 14.4);
  height: var(--H);
}
#disc .tx .lv {
  position: relative;
  --img: url(../assets/ui/pill-green.webp);
  --ka: 2.346;
  --H: calc(1.25em + var(--u) * 0.4);
  height: var(--H);
  line-height: 1.25;
}
#disc .pl {
  height: calc(var(--u) * 11);
  filter: drop-shadow(0 calc(var(--u) * 0.4) 0 rgba(58, 36, 22, 0.25));
}
#disc .tx {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--u) * 0.4);
}
#disc .tx b {
  font-size: max(13px, calc(var(--u) * 3.8));
  white-space: nowrap;
}
#disc .tx .lv {
  font-size: max(11px, calc(var(--u) * 2.8));
  padding: calc(var(--u) * 0.2) calc(var(--u) * 1.8);
}
#disc .sp {
  position: absolute;
  top: calc(var(--u) * -1.2);
  height: calc(var(--u) * 4);
  animation: discsp 0.5s ease-out both;
}
#disc .sp.l {
  left: calc(var(--u) * -4);
}
#disc .sp.r {
  right: calc(var(--u) * -4);
}
@keyframes discin {
  0% {
    transform: translateY(calc(var(--u) * -5));
    opacity: 0;
    animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.6);
  }
  28% {
    opacity: 1;
  }
  55% {
    transform: translateY(calc(var(--u) * 0.7)) scale(1.03, 0.96);
    opacity: 1;
    animation-timing-function: ease-out;
  }
  80% {
    transform: translateY(calc(var(--u) * -0.2)) scale(0.995, 1.01);
  }
  100% {
    transform: none;
  }
}
@keyframes discrib {
  0% {
    transform: translateY(calc(var(--u) * -4)) rotate(-3deg);
    opacity: 0;
    animation-timing-function: cubic-bezier(0.5, 0, 0.9, 0.6);
  }
  60% {
    transform: translateY(calc(var(--u) * 0.5)) rotate(0.6deg);
    opacity: 1;
    animation-timing-function: ease-out;
  }
  100% {
    transform: none;
  }
}
@keyframes discpop {
  0% {
    transform: scale(0.7);
  }
  60% {
    transform: scale(1.08);
  }
  100% {
    transform: none;
  }
}
@keyframes discout {
  to {
    transform: translateY(calc(var(--u) * -1.5)) scale(0.9);
    opacity: 0;
  }
}
@keyframes discsp {
  0% {
    transform: scale(0.3);
    opacity: 0;
  }
  40% {
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 0.9;
  }
}
.reduced #disc .in,
.reduced #disc.out .in,
.reduced #disc .sp {
  animation: fadein 0.18s both !important;
}
.reduced #disc.out .in {
  animation: fadeout 0.15s forwards !important;
}
@keyframes fadein {
  from {
    opacity: 0;
  }
}
@keyframes fadeout {
  to {
    opacity: 0;
  }
}

/* boss entrance: the strip drops in from above with a small bounce, the crown hops a beat later (scale only, ±8%) */
#boss-strip.enter {
  animation: bossin 0.55s cubic-bezier(0.2, 1.5, 0.4, 1) both;
}
#boss-strip.enter .bcrown {
  animation: crownhop 0.5s 0.35s ease-out both;
}
@keyframes bossin {
  from {
    transform: translateY(calc(var(--u) * -12)) scale(0.92);
    opacity: 0;
  }
  60% {
    opacity: 1;
  }
}
@keyframes crownhop {
  40% {
    transform: translateY(calc(var(--u) * -2)) rotate(-18deg);
  }
  100% {
    transform: rotate(-12deg);
  }
}
.reduced #boss-strip.enter,
.reduced #boss-strip.enter .bcrown {
  animation: fadein 0.3s both;
}

/* reset progress: a small quiet pill under Continue; armed (second tap erases) it turns warm amber and wiggles once */
#title .reset {
  position: absolute;
  left: calc(var(--u) * 29.5);
  top: 77.2%;
  width: 26.6%;
  height: 6%;
  background: none;
  border: 0;
  padding: 0;
  display: grid;
  place-items: center;
}
#title .reset[hidden] {
  display: none;
}
#title .reset span {
  position: relative;
  --img: url(../assets/ui/pill-cream.webp);
  --ka: 1.886;
  --H: calc(var(--u) * 6);
  height: 100%;
  display: grid;
  place-items: center;
  padding: 0 calc(var(--u) * 5.6);
  font-size: max(10px, calc(var(--u) * 2.8));
  white-space: nowrap;
  opacity: 0.9;
}
#title .reset.arm span {
  --img: url(../assets/ui/btn-gold.webp);
  --ka: 2.648;
  opacity: 1;
  animation: armwiggle 0.35s ease-out;
}
@keyframes armwiggle {
  30% {
    transform: rotate(-2deg) scale(1.04);
  }
  65% {
    transform: rotate(2deg);
  }
}
.reduced #title .reset.arm span {
  animation: none;
}

/* tap to start (first touch unlocks sound on iPhone): same backdrop as the rotate screen, a pill with a passing light */
#boot.ready {
  cursor: pointer;
}
/* no slices (slices left a seam line): the flat middle of the picture stretches under the text,
   and the two rounded ends are the whole picture at its real proportion, fading into that middle. Any text length fits. */
#boot .tap {
  --th: calc(4.8vmin + 1.2 * clamp(20px, 4.2vmin, 34px));
  position: relative;
  isolation: isolate;
  margin: 0;
  height: var(--th);
  padding: 0 calc(var(--th) * 0.72);
  white-space: nowrap;
  background:
    linear-gradient(100deg, transparent 25%, rgba(255, 255, 255, 0.6) 50%, transparent 75%) -60% 0 / 28% 100% no-repeat
      content-box,
    url(../assets/ui/btn-pill.webp) center / 1000% 100% no-repeat content-box;
  filter: drop-shadow(0 5px 0 rgba(58, 36, 22, 0.3));
  color: var(--ink);
  font: 700 clamp(20px, 4.2vmin, 34px) / 1.2 var(--font);
  animation: tapshine 3s ease-in-out infinite;
  line-height: var(--th);
}
#boot .tap::before,
#boot .tap::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url(../assets/ui/btn-pill.webp) left center / auto 100% no-repeat;
  -webkit-mask-image: linear-gradient(90deg, #000 var(--th), transparent calc(var(--th) * 1.4));
  mask-image: linear-gradient(90deg, #000 var(--th), transparent calc(var(--th) * 1.4));
}
#boot .tap::after {
  background-position: right center;
  -webkit-mask-image: linear-gradient(270deg, #000 var(--th), transparent calc(var(--th) * 1.4));
  mask-image: linear-gradient(270deg, #000 var(--th), transparent calc(var(--th) * 1.4));
}
@keyframes tapshine {
  0%,
  50% {
    background-position:
      -60% 0,
      center;
  }
  100% {
    background-position:
      160% 0,
      center;
  }
} /* a light passes; the pill never changes size */
#boot.out {
  opacity: 0;
  transition: opacity 0.3s;
}
.reduced #boot .tap {
  animation: none;
}

/* ================================================================ Dragon Roost: sizes of the themed pieces
   (the slice values below are in px of those images) */
/* wave plate: the whole image (wing on the top left, outside the text box); the text sits on the crimson face */
#wave-chip {
  left: calc(var(--u) * 5.1);
  top: calc(var(--u) * 0.7);
  width: calc(var(--u) * 23.2);
  height: calc(var(--u) * 5.6);
  font-size: max(12px, calc(var(--u) * 3.4));
}
#wave-chip {
  --img: url(../assets/ui/wave-plate.webp);
}
#wave-chip::before {
  inset: calc(var(--u) * -1.67) calc(var(--u) * -0.94) 0 calc(var(--u) * -4.36);
}
#wave-chip span {
  margin-top: 0;
}
#wave-chip .ol,
#wave-chip.ol {
  --o: calc(var(--u) * 0.34);
}
/* wall bar: dragon shield on the left, dark track, crest in the middle: the whole image (the box keeps its proportion) */
#fence {
  --img: url(../assets/ui/hp-frame.webp);
}
#fence .track {
  left: calc(var(--u) * 8.25);
  right: calc(var(--u) * 2.8);
  top: calc(var(--u) * 2.85);
  bottom: calc(var(--u) * 2.4);
}
/* the number sits on the middle of the bar itself (the track runs from 2.85u to 5.9u) and is no taller than it */
#fence .num {
  left: calc(var(--u) * 8.25 + (100% - var(--u) * 11.05) / 2);
  top: calc(var(--u) * 4.38);
  transform: translate(-50%, -50%);
  font-size: max(11px, calc(var(--u) * 2.7));
}
/* boss band: plum wood with golden claws at the ends (the claws go past the band). The box is almost the image size,
   so it uses the whole image twice (one pinned left, one pinned right) blended in the plain middle. */
#boss-strip::before,
#boss-strip::after {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: auto;
  border: 0;
  padding: 0;
  background: url(../assets/ui/boss-strip.webp) left center / auto 100% no-repeat;
  -webkit-mask-image: linear-gradient(90deg, #000 44%, transparent 56%);
  mask-image: linear-gradient(90deg, #000 44%, transparent 56%);
}
#boss-strip::after {
  background-position: right center;
  -webkit-mask-image: linear-gradient(90deg, transparent 44%, #000 56%);
  mask-image: linear-gradient(90deg, transparent 44%, #000 56%);
}
#boss-strip .bb {
  background: #2a1420;
}
/* bottom bar: each button is the same whole image twice, at its real proportion (one pinned left, one pinned right)
   with a soft blend in the plain middle. Nothing stretches and there are no slices, so pressing never shows a seam. */
#dock .dbtn.nine::before,
#dock .dbtn::after {
  content: '';
  position: absolute;
  inset: 0;
  width: auto;
  z-index: -1;
  pointer-events: none;
  border: 0;
  padding: 0;
  background-repeat: no-repeat;
  background-size: auto 100%;
  background-origin: padding-box;
  background-clip: border-box;
}
#dock .dbtn.nine::before {
  background-position: left center;
  -webkit-mask-image: linear-gradient(90deg, #000 60%, transparent 62%);
  mask-image: linear-gradient(90deg, #000 60%, transparent 62%);
}
#dock .dbtn::after {
  background-position: right center;
  -webkit-mask-image: linear-gradient(90deg, transparent 42%, #000 58%);
  mask-image: linear-gradient(90deg, transparent 42%, #000 58%);
}
#btn-plant::before,
#btn-plant::after,
#btn-bees::before,
#btn-bees::after,
#btn-fert::before,
#btn-fert::after,
#btn-shed::before,
#btn-shed::after {
  background-image: url(../assets/ui/btn-cream.webp);
}
#btn-call::before,
#btn-call::after {
  background-image: url(../assets/ui/btn-orange.webp);
}
.dbtn,
#btn-speed {
  padding-bottom: calc(var(--u) * 1.1);
} /* the pennant tips hang below the plate */
#btn-call {
  padding-bottom: 0;
}
/* Play: ivory face, brown letters */
#title .play {
  color: var(--ink);
  text-shadow: 0 calc(var(--u) * 0.45) 0 rgba(255, 255, 255, 0.55);
  padding-bottom: calc(var(--u) * 0.4);
}
/* new dragon card: crimson band with wings */
#disc .rb {
  --img: url(../assets/ui/ribbon-win.webp);
  --H: calc(var(--u) * 10);
  height: var(--H);
  min-width: calc(var(--u) * 44);
}
#disc .rb span {
  position: relative;
  top: calc(var(--u) * 1.36);
  margin-top: 0;
  font-size: calc(var(--u) * 3.6);
}
#disc .card {
  margin-top: calc(var(--u) * -0.6);
}
#boss-strip .bn,
#boss-strip .bb {
  margin-right: calc(var(--u) * 11.5);
}
/* name and bar stay inside the dark band (clear of the golden rim), the percentage is read on the bar itself, like
   the Wall's number, instead of over the claw on the right */
#boss-strip {
  gap: calc(var(--u) * 0.7);
}
#boss-strip .bn {
  font-size: calc(var(--u) * 2.9);
}
#boss-strip .bb {
  height: calc(var(--u) * 2.8);
}
#boss-strip .bpct {
  right: auto;
  bottom: auto;
  left: calc(var(--u) * 30.65);
  top: calc(var(--u) * 7.1);
  transform: translate(-50%, -50%);
  font-size: calc(var(--u) * 2.5);
  --o: calc(var(--u) * 0.32);
  /* outline only: the usual drop shadow of .ol would fall below the thin bar as a ghost of the number */
  text-shadow:
    var(--o) 0 var(--ink),
    calc(var(--o) * -1) 0 var(--ink),
    0 var(--o) var(--ink),
    0 calc(var(--o) * -1) var(--ink),
    calc(var(--o) * 0.7) calc(var(--o) * 0.7) var(--ink),
    calc(var(--o) * -0.7) calc(var(--o) * 0.7) var(--ink),
    calc(var(--o) * 0.7) calc(var(--o) * -0.7) var(--ink),
    calc(var(--o) * -0.7) calc(var(--o) * -0.7) var(--ink);
}
#hud.calling #btn-fert .ring {
  bottom: calc(var(--u) * 1.7);
}
/* ---------------------------------------------------------------- mascot call-out (src/app/callout.js)
   Bottom right corner of the window (not of the stage: on a wide screen the corner is the window's), pointing left: a slanted band sweeps in behind him, he slides in, speaks, leaves.
   Touches go through; his boots stay below the edge. Never a full-screen flash. */
#callout {
  position: absolute;
  right: 0;
  bottom: 0;
  width: calc(var(--u) * 50);
  height: calc(var(--u) * 40);
  overflow: hidden;
  pointer-events: none;
}
#callout[hidden] {
  display: none;
}
#callout .band {
  position: absolute;
  left: calc(var(--u) * 9);
  right: calc(var(--u) * -10);
  bottom: calc(var(--u) * 4);
  height: calc(var(--u) * 19);
  transform: skewX(-16deg);
  transform-origin: 100% 100%;
  background:
    repeating-linear-gradient(
      90deg,
      rgba(255, 236, 170, 0.16) 0 calc(var(--u) * 0.5),
      transparent calc(var(--u) * 0.5) calc(var(--u) * 4.5)
    ),
    linear-gradient(
      180deg,
      #ffd660 0 7%,
      #3a2416 7% 9.5%,
      #c41f37 9.5% 50%,
      #8a1228 50% 90.5%,
      #3a2416 90.5% 93%,
      #ffd660 93%
    );
  border-left: calc(var(--u) * 0.5) solid #3a2416;
  box-shadow: calc(var(--u) * -1.2) 0 0 rgba(255, 244, 220, 0.55);
}
#callout img {
  position: absolute;
  right: calc(var(--u) * -2);
  bottom: calc(var(--u) * -7);
  height: calc(var(--u) * 41);
  filter: drop-shadow(0 0 calc(var(--u) * 0.5) #fff4dc);
  transform-origin: 80% 100%;
}
#callout.in .band {
  animation: co-band 0.22s cubic-bezier(0.2, 0.9, 0.3, 1) both;
}
#callout.in img {
  animation:
    co-in 0.3s cubic-bezier(0.3, 1.5, 0.5, 1) both,
    co-talk 0.32s ease-in-out 0.3s infinite alternate;
}
#callout.out .band,
#callout.out img {
  animation: co-out 0.22s ease-in both;
}
@keyframes co-band {
  from {
    transform: skewX(-16deg) translateX(110%);
  }
  to {
    transform: skewX(-16deg);
  }
}
@keyframes co-in {
  from {
    transform: translateX(105%) rotate(6deg);
  }
  to {
    transform: none;
  }
}
@keyframes co-talk {
  from {
    transform: none;
  }
  to {
    transform: translateY(calc(var(--u) * -0.5)) rotate(-1.2deg);
  }
}
@keyframes co-out {
  to {
    transform: translateX(115%);
    opacity: 0;
  }
}
#callout.out .band {
  transform: skewX(-16deg);
}
.reduced #callout.in .band,
.reduced #callout.in img {
  animation: co-fade 0.2s both;
}
.reduced #callout.out .band,
.reduced #callout.out img {
  animation: co-fade 0.2s reverse both;
}
@keyframes co-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.paused #callout * {
  animation-play-state: paused !important;
}

/* End of css/game.css */
