/* PRESENTS ON THE PATH — see assets/presents.js. Each stone that has not
   been reached yet has a wrapped present sitting beside it; reaching the
   stone opens it. This is what the path is FOR. */
.gift .g-box { fill: #FF8FA6; stroke: #E0607F; stroke-width: 1.1; }
.gift .g-rib { fill: #FFCE3D; }
.gift .g-lid { fill: #FF9EC0; stroke: #E0607F; stroke-width: 1.1; transform-box: fill-box; transform-origin: 50% 100%; }
.gift .g-bow { fill: none; stroke: #FFCE3D; stroke-width: 1.6; stroke-linecap: round; }
.gift.closed .g-in { animation: giftWiggle 3.2s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
.gift.closed.next .g-in { animation: giftBounce 1.4s var(--spring) infinite; }
.gift.opened .g-lid, .gift.opened .g-bow { display: none; }
.gift.opened .g-box { fill: #FFE7B4; stroke: #E2A81F; }
.gift.opened .g-star { fill: #FFCE3D; stroke: #E2A81F; stroke-width: .8; }
.gift .g-star { display: none; }
.gift.opened .g-star { display: block; animation: giftTwinkle 1.8s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 50%; }
.gift.opening .g-lid { animation: giftLid .9s var(--spring) forwards; }
.gift.opening .g-bow { animation: giftLid .9s var(--spring) forwards; transform-box: fill-box; transform-origin: 50% 100%; }
@keyframes giftWiggle { 0%,100%{transform:rotate(0)} 50%{transform:rotate(-4deg)} }
@keyframes giftBounce { 0%,100%{transform:translateY(0) scale(1)} 40%{transform:translateY(-4px) scale(1.08)} }
@keyframes giftTwinkle { 0%,100%{transform:scale(1) rotate(0)} 50%{transform:scale(1.25) rotate(18deg)} }
@keyframes giftLid { 0%{transform:none;opacity:1} 60%{transform:translateY(-18px) rotate(-30deg);opacity:1} 100%{transform:translateY(-30px) rotate(-50deg);opacity:0} }

/* the reveal card reuses #prizePop; a place gets a little caption under it */
#prizePop i { display: block; font-size: clamp(12px, 3.3vw, 15px); color: var(--ink-soft); font-style: normal; margin-top: 2px; font-weight: 600; }
#prizePop.place svg { width: clamp(110px, 30vw, 150px); }

/* the soft wipe between somewhere new and the games — see tour.js */
#wipe { position: fixed; inset: 0; z-index: 950; pointer-events: none; opacity: 0; transition: opacity .4s ease;
  background: radial-gradient(60% 40% at 50% 42%, #FFF9E6, transparent 72%), linear-gradient(180deg, #DDF1FF 0%, #FFF3D8 100%); }
#wipe.on { opacity: 1; pointer-events: auto; }
#wipe .w-sun { position: absolute; left: 50%; top: 40%; width: 26vw; height: 26vw; max-width: 130px; max-height: 130px;
  border-radius: 50%; transform: translate(-50%, -50%) scale(.6); background: radial-gradient(circle at 40% 36%, #FFE79A, var(--sun) 60%, #F3B21E);
  box-shadow: 0 0 60px 20px rgba(255,206,61,.35); transition: transform .5s var(--spring); }
#wipe.on .w-sun { transform: translate(-50%, -50%) scale(1); }

/* ---------------------------------------------------- the walk, side on */
.walk { position: relative; width: min(100vw, 520px); height: min(46vh, 380px); overflow: hidden; border-radius: 28px;
  box-shadow: 0 18px 40px rgba(59,42,30,.16), var(--gloss); flex: none; }
.walk::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 4px; z-index: 6; pointer-events: none;
  background: linear-gradient(135deg, var(--sun), var(--sky));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; }
.wk-sky { position: absolute; inset: 0; background: linear-gradient(180deg, #CFEBFF 0%, #E9F6FF 60%, #F7F3E4 100%); }
.wk-sun { position: absolute; right: 9%; top: 8%; width: 16%; padding-bottom: 16%; border-radius: 50%;
  background: radial-gradient(circle at 40% 36%, #FFE79A, var(--sun) 62%, #F3B21E); box-shadow: 0 0 34px 10px rgba(255,206,61,.35); }
.wk-cloud { position: absolute; top: 14%; width: 22%; height: 9%; border-radius: 40px; background: #fff; opacity: .9; }
.wk-cloud::before { content: ''; position: absolute; left: 22%; top: -55%; width: 44%; height: 120%; border-radius: 50%; background: #fff; }
.wk-cloud.c1 { left: 8%; } .wk-cloud.c2 { left: 48%; top: 22%; width: 16%; height: 7%; opacity: .75; }
.wk-hill { position: absolute; bottom: 30%; border-radius: 50% 50% 0 0; }
.wk-hill.h1 { left: -12%; width: 70%; height: 36%; background: linear-gradient(180deg, #A9DD8E, #8AD37F); }
.wk-hill.h2 { right: -16%; width: 74%; height: 42%; background: linear-gradient(180deg, #98D686, #74C46A); }
.wk-ground { position: absolute; left: 0; right: 0; bottom: 0; height: 34%; background: linear-gradient(180deg, #8AD37F, #6BBE62); }
.wk-road { position: absolute; left: -4%; right: -4%; bottom: 13%; height: 11%; border-radius: 20px;
  background: linear-gradient(180deg, #EAD6AE, #D9BE8D); box-shadow: inset 0 3px 0 rgba(255,255,255,.35); }
.wk-road::after { content: ''; position: absolute; left: 0; right: 0; top: 46%; height: 3px;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.7) 0 14px, transparent 14px 26px); }

.wk-stop { position: absolute; bottom: 20%; width: 0; }
.wk-post { position: absolute; left: -4px; bottom: 6px; width: 8px; height: 46px; border-radius: 4px; background: linear-gradient(90deg, #B98A50, #8E5F2B); }
.wk-sign { position: absolute; left: 50%; top: -30px; transform: translateX(-50%); min-width: 34px; height: 34px; padding: 0 6px;
  border-radius: 12px; background: #FFF6E9; color: #C9B79E; font-weight: 800; font-size: 20px; display: grid; place-items: center;
  box-shadow: 0 0 0 3px #DCCBB2, 0 6px 12px rgba(59,42,30,.16); }
.wk-stop.done .wk-sign { background: #8AD37F; color: #fff; box-shadow: 0 0 0 3px #5FAE58, 0 6px 12px rgba(59,42,30,.16); }
.wk-gift { position: absolute; left: 10px; bottom: 0; width: 40px; height: 40px; }
.wk-gift .gift-svg { width: 100%; height: 100%; overflow: visible; display: block; }
.wk-gift.closed .g-in { animation: giftWiggle 3.2s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
.wk-gift.closed.next .g-in { animation: giftBounce 1.4s var(--spring) infinite; }
.wk-gift.opened .g-lid, .wk-gift.opened .g-bow { display: none; }
.wk-gift.opened .g-box { fill: #FFE7B4; stroke: #E2A81F; }
.wk-gift.opened .g-star { display: block; fill: #FFCE3D; stroke: #E2A81F; stroke-width: .8; animation: giftTwinkle 1.8s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 50%; }
.wk-gift.opening .g-lid, .wk-gift.opening .g-bow { animation: giftLid .9s var(--spring) forwards; transform-box: fill-box; transform-origin: 50% 100%; }

.wk-goal { position: absolute; left: 91%; bottom: 31%; transform: translateX(-50%); width: 20%; text-align: center; }
.wk-goal svg { width: 100%; height: auto; display: block; filter: drop-shadow(0 6px 8px rgba(59,42,30,.18)); }
.wk-goal b { display: block; font-size: clamp(10px, 2.8vw, 13px); color: var(--ink); margin-top: 2px; white-space: nowrap; }
.wk-goal.arrived svg { animation: goalHere 1.6s var(--spring) infinite; }

.wk-mo { position: absolute; left: 9%; bottom: 16%; width: 21%; max-width: 110px; transform: translateX(-50%); z-index: 4; }
.wk-mo .char { width: 100%; }
.wk-mo .char svg { width: 100%; height: auto; display: block; overflow: visible; }
.wk-mo.walking { animation: wkBob .34s ease-in-out infinite; }
@keyframes wkBob { 0%,100% { transform: translateX(-50%) translateY(0) rotate(-2deg); } 50% { transform: translateX(-50%) translateY(-7px) rotate(2deg); } }

#scPrize .prize-row { margin-top: 4px; }
body.no-asking #scPrize .prize-row { display: none; }
#scPrize.rolling .prize-row { display: none; }

/* Pip on the road — she flies along at Mo's shoulder (see placeMo). Only
   with the balloon present switched on ('gift-balloon'). */
body:not(.gf-feature) .wk-pip { display: none; }
.wk-pip { position: absolute; left: 4%; bottom: 40%; width: 12%; max-width: 64px; transform: translateX(-50%); z-index: 3; }
.wk-pip .char { width: 100%; }
.wk-pip .char svg { width: 100%; height: auto; display: block; overflow: visible; }
.wk-pip.walking { animation: wkBob .3s ease-in-out infinite; }

/* ---------------------------------------- THE DELIVERY — see deliver()
   A striped hot-air balloon brings a BIG present down onto the road. The
   colours are variables, one set per present, so no two in a row match. */
.walk, #gfStage {
  --gf-string: #9C7A55;
  --gf-wicker: #B7834A; --gf-wicker-dk: #8E5F2B;
}
.gf-c0 { --gb: #FF5FA2; --gl: #FF86BC; --gr: var(--sun);  --gd: #FFC2DC; --be: #FF6B6B; --bs: var(--sun);  --bm: #FFFFFF; }
.gf-c1 { --gb: #3FA2F0; --gl: #6DBCF7; --gr: var(--sun);  --gd: #BFE3FF; --be: var(--grape); --bs: #FFFFFF; --bm: var(--berry); }
.gf-c2 { --gb: #9466F2; --gl: #B08CFA; --gr: #7DE3B0;     --gd: #DCCBFF; --be: var(--leaf); --bs: var(--sun);  --bm: #FF8A3D; }
.gf-c3 { --gb: #22B888; --gl: #4ED3A5; --gr: #FF7BA0;     --gd: #B5F0DA; --be: #FF8A3D; --bs: #FFFFFF;    --bm: var(--sky); }

.gf-drop { position: absolute; left: 50%; bottom: calc(var(--band, 0px) - 14px); width: var(--gw); transform: translateX(-50%); z-index: 5; pointer-events: none; }
.gf-bal { position: absolute; left: 10%; width: 80%; bottom: 72%; transform-origin: 50% 100%; }
.gf-bal-svg { display: block; width: 100%; height: auto; overflow: visible; animation: gfSway 2.4s ease-in-out infinite; transform-origin: 50% 100%; }
.gf-env { fill: var(--be); }
.gf-gore { fill: var(--bs); }
.gf-mid { fill: var(--bm); }
.gf-hi { fill: #fff; opacity: .4; }
.gf-cord, .gf-rope { stroke: var(--gf-string); stroke-width: 1.6; fill: none; stroke-linecap: round; }
.gf-basket { fill: var(--gf-wicker); stroke: var(--gf-wicker-dk); stroke-width: 1.4; }
.gf-weave { stroke: var(--gf-wicker-dk); stroke-width: 1; fill: none; opacity: .7; }

.gf-gift { position: relative; display: block; width: 100%; padding: 0; margin: 0; border: 0; background: none; cursor: pointer;
  pointer-events: none; touch-action: manipulation; -webkit-tap-highlight-color: transparent; font: inherit; }
.gf-gift.ready, .gf-gift.open { pointer-events: auto; }
.gf-svg { position: relative; display: block; width: 100%; height: auto; overflow: visible; transform-origin: 50% 95%; }
.gf-box { fill: var(--gb); }
.gf-lidbox { fill: var(--gl); }
.gf-band { fill: var(--gr); }
.gf-dot { fill: var(--gd); }
.gf-shine { fill: #fff; opacity: .45; }
.gf-inside { fill: rgba(59,42,30,.35); opacity: 0; }
.gf-gift.open .gf-inside { opacity: 1; }
.gf-bow, .gf-tail, .gf-knot { fill: var(--gr); stroke: rgba(59,42,30,.18); stroke-width: 1; }
.gf-shadow { fill: rgba(59,42,30,.18); }
.gf-rays path { fill: var(--sun); opacity: .8; }
.gf-rays { opacity: 0; transform-box: view-box; transform-origin: 70px 66px; }
.gf-lid { transform-box: view-box; transform-origin: 70px 50px; }
.gf-body { transform-box: view-box; transform-origin: 70px 120px; }
.gf-halo { position: absolute; left: 50%; top: 58%; width: 150%; height: 150%; transform: translate(-50%, -50%) scale(.6); border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,240,170,.95), rgba(255,206,61,.45) 55%, rgba(255,206,61,0)); opacity: 0; pointer-events: none; }

/* hanging under the balloon it swings a little; landing squashes it */
.gf-gift.falling .gf-svg { animation: gfSwing 2.4s ease-in-out infinite; }
.gf-gift.land .gf-svg { animation: gfLand .6s var(--spring); }
/* waiting for a finger: it glows, wobbles and keeps hopping */
.gf-gift.ready .gf-halo { animation: gfGlow 1.6s ease-in-out infinite; }
.gf-gift.ready:not(.land) .gf-svg { animation: gfWait 1.5s var(--spring) infinite; }
.gf-gift.ready.nudge .gf-svg { animation: gfNudge .5s var(--spring) 3; }
.gf-gift.jig .gf-svg { animation: gfJig .35s var(--spring); }
/* opened: the lid springs off, the box bounces, the light pours out */
.gf-gift.open .gf-lid { animation: gfLidOff 1.1s var(--spring) forwards; }
.gf-gift.open .gf-body { animation: gfBoxPop .6s var(--spring); }
.gf-gift.open .gf-rays { opacity: 1; animation: gfRays 6s linear infinite, gfRaysIn .6s var(--spring); }
.gf-gift.open .gf-halo { opacity: 1; transform: translate(-50%, -50%) scale(1); transition: transform .6s var(--spring); }

@keyframes gfSway { 0%,100% { transform: rotate(-3deg); } 50% { transform: rotate(3deg); } }
@keyframes gfSwing { 0%,100% { transform: rotate(3deg); } 50% { transform: rotate(-3deg); } }
@keyframes gfLand { 0% { transform: scale(1.12, .8); } 55% { transform: scale(.94, 1.08); } 100% { transform: none; } }
@keyframes gfWait { 0%,100% { transform: none; } 18% { transform: translateY(-9%) rotate(-5deg) scale(1.04); } 36% { transform: rotate(4deg); } 50% { transform: none; } }
@keyframes gfNudge { 0%,100% { transform: none; } 40% { transform: translateY(-22%) scale(1.12) rotate(-6deg); } 70% { transform: scale(1.1, .9); } }
@keyframes gfJig { 0%,100% { transform: none; } 50% { transform: scale(1.08) rotate(4deg); } }
@keyframes gfGlow { 0%,100% { opacity: .55; transform: translate(-50%, -50%) scale(.85); } 50% { opacity: 1; transform: translate(-50%, -50%) scale(1.05); } }
@keyframes gfLidOff { 0% { transform: none; } 35% { transform: translate(-6px, -70px) rotate(-22deg); opacity: 1; } 100% { transform: translate(-46px, -40px) rotate(-70deg) scale(.8); opacity: 0; } }
@keyframes gfBoxPop { 0% { transform: scale(1.18, .8); } 60% { transform: scale(.94, 1.08); } 100% { transform: none; } }
@keyframes gfRays { to { transform: rotate(360deg); } }
@keyframes gfRaysIn { from { opacity: 0; } to { opacity: 1; } }

/* little party balloons that fly up when it lands and when it opens */
.gf-pb { position: absolute; bottom: calc(var(--band, 0px) + 10px); width: clamp(32px, 8vw, 64px); z-index: 6; pointer-events: none; transform: translateX(-50%);
  animation: gfRise 3.8s ease-in forwards; opacity: 0; }
.gf-pb svg { display: block; width: 100%; height: auto; }
.gf-pb.b0 { --pc: var(--berry); } .gf-pb.b1 { --pc: var(--sun); } .gf-pb.b2 { --pc: var(--sky); }
.gf-pb.b3 { --pc: var(--leaf); } .gf-pb.b4 { --pc: var(--grape); } .gf-pb.b5 { --pc: var(--honey); }
@keyframes gfRise {
  0% { opacity: 0; transform: translate(-50%, 0) scale(.4); }
  12% { opacity: 1; transform: translate(-50%, -20px) scale(1); }
  50% { transform: translate(calc(-50% + var(--sway, 12px)), calc(var(--rise, -420px) * .4)); }
  100% { opacity: 1; transform: translate(calc(-50% - var(--sway, 12px)), var(--rise, -420px)); }
}

/* the reward comes UP OUT OF THE PRESENT: it starts at the present, small,
   and springs up to the middle bigger than any other prize card */
body.gf-on #prizePop.from-gift { transform: translate(calc(-50% + var(--fx, 0px)), calc(-50% + var(--fy, 0px))) scale(.15); }
body.gf-on #prizePop.from-gift { top: 33%; z-index: 61; }
body.gf-on #prizePop.from-gift.on { transform: translate(-50%, -50%) scale(1.3); transition: opacity .25s, transform .8s var(--spring); }
body.gf-on #prizePop.from-gift svg { width: clamp(120px, 32vw, 190px); }

/* whatever was standing where the present landed steps out of its way */
body.gf-feature .wk-stop { transition: opacity .5s ease; }
body.gf-on .wk-stop.gf-under { opacity: .18; }

/* ON A TABLET THE ROAD WAS A POSTCARD in the middle of the screen — 520 wide
   on a 1180 screen, with the present a sixth of that. The celebration is the
   reward, so on a big screen the whole scene is drawn big. */
@media (min-width: 760px) and (min-height: 640px) {
  body.gf-feature .walk { width: min(64vw, 760px); height: min(56vh, 480px); }
  body.gf-feature .wk-mo { max-width: 150px; }
  body.gf-feature .wk-pip { max-width: 88px; }
  body.gf-feature .wk-gift { width: 52px; height: 52px; }
}
body.gf-on #prizePop.from-gift i { white-space: nowrap; }

/* ------------------------------------------------- THE WHOLE-SCREEN SKY
   The celebration opens out of the road card to fill the screen (#gfStage,
   built by deliver()). It lives inside the prize screen (z 2) at z 20, so
   the way-out button (z 24) stays above it, and the cast band (z 6) stands
   in front of the whole screen, so the real Mo is on its grass; the
   grass top is the top of the band, --band, measured when it opens. */
#gfStage { position: fixed; inset: 0; z-index: 20; display: none; overflow: hidden; pointer-events: none; }
#gfStage.on { display: block; }
.gfs-sky { position: absolute; inset: 0;
  background: radial-gradient(70% 50% at 50% 30%, rgba(255,249,228,.9), transparent 70%),
              linear-gradient(180deg, #9FD8FF 0%, #CFEBFF 45%, #EAF7FF 75%, #FFF6DD 100%); }
.gfs-sun { position: absolute; right: 8%; top: 7%; width: clamp(70px, 18vmin, 170px); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 40% 36%, #FFE79A, var(--sun) 62%, #F3B21E); box-shadow: 0 0 60px 22px rgba(255,206,61,.4);
  animation: gfsSun 6s ease-in-out infinite; }
@keyframes gfsSun { 50% { transform: scale(1.06); box-shadow: 0 0 80px 30px rgba(255,206,61,.5); } }
.gfs-cloud { position: absolute; height: clamp(26px, 6vmin, 56px); border-radius: 60px; background: #fff; opacity: .92; animation: gfsDrift 14s linear infinite alternate; }
.gfs-cloud::before { content: ''; position: absolute; left: 22%; top: -60%; width: 46%; height: 130%; border-radius: 50%; background: #fff; }
.gfs-cloud.c1 { left: 6%; top: 12%; width: clamp(110px, 26vw, 260px); }
.gfs-cloud.c2 { left: 52%; top: 26%; width: clamp(80px, 18vw, 190px); opacity: .8; animation-duration: 18s; }
.gfs-cloud.c3 { left: 20%; top: 40%; width: clamp(70px, 14vw, 150px); opacity: .7; animation-duration: 11s; }
@keyframes gfsDrift { to { transform: translateX(6vw); } }
.gfs-hill { position: absolute; border-radius: 50% 50% 0 0 / 100% 100% 0 0; }
.gfs-hill.h1 { left: -15%; width: 75%; bottom: calc(var(--band, 0px) - 40px); height: 26vh; background: linear-gradient(180deg, #A9DD8E, #8AD37F); }
.gfs-hill.h2 { right: -20%; width: 80%; bottom: calc(var(--band, 0px) - 40px); height: 32vh; background: linear-gradient(180deg, #98D686, #74C46A); }
.gfs-ground { position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--band, 0px) + 6px);
  background: linear-gradient(180deg, #8AD37F, #5FB458); box-shadow: 0 -2px 0 rgba(255,255,255,.35) inset; }
/* Pip, when the band's own Pip is not on: where the band would put her */
.gfs-pip { position: absolute; right: clamp(6px, 3vw, 32px); bottom: calc(var(--pad-bot, 0px) + 6px); width: clamp(86px, 20vw, 138px); display: none; }
#gfStage.with-pip .gfs-pip { display: block; }
.gfs-pip .char { width: 100%; }
.gfs-pip .char svg { width: 100%; height: auto; display: block; overflow: visible; }
#gfStage .gf-gift.ready, #gfStage .gf-gift.open { pointer-events: auto; }
