/* The opening slide.
 *
 * Every delay here reads a custom property that intro.js writes from BEATS, so
 * this file says what happens and BEATS says when. Durations and easings stay
 * here: they are the character of a move, not its timing.
 *
 * Nothing plays until the .run class lands on the SVG. The base state of each
 * animated element is its own first frame, so the slide can be built, cloned
 * into the overview, or sat on with the animation stopped without anything
 * flashing into view.
 */
.intro{position:absolute;inset:0}
.intro-art{position:absolute;inset:0;width:100%;height:100%;display:block}
.intro-art *{transform-box:view-box}

/* ---------- base state: the first frame of everything that moves ---------- */
.title{clip-path:inset(0 100% 0 0)}
/* The title and the standfirst open large and centred and travel to the corner
   together. Where they start is measured off the laid-out type at run time and
   written onto the SVG by intro.js: the card is then centred and unclipped
   whatever font actually loads, and changing the copy or its size needs no
   remeasuring by hand. The values below are only the fallback for when that
   measurement cannot run. Their resting positions are still authored in the
   markup, and nothing that has to register with the type is measured at all:
   the drops still fly to coordinates the agenda is set from. */
.titleWrap,.stand{transform-box:fill-box;transform-origin:50% 50%}
.titleWrap{transform:translate(var(--tdx,340px),var(--tdy,176px)) scale(var(--tsc,2.15))}
.stand{transform:translate(var(--sdx,300px),var(--sdy,200px)) scale(var(--ssc,1.6))}
.rule{transform:scaleX(0);transform-origin:90px 154px}
.item,.hatch,.ground,.vessels,.screw{opacity:0}
/* Far enough off the left edge that nothing of it is in frame before it comes
   in. The hand reaches further right than the glass does, so this is measured
   off the hand, not the glass. */
.glassRig{transform:translate(-780px,26px)}
.rig{transform-origin:960px 600px}
.level{transform-origin:600px 415px}
.handle{transform-origin:960px 107px}
/* Both the agenda drops and the splash fly head first: offset-rotate:auto puts
   the shape's own +x along the direction of travel. */
.drop{offset-distance:0%;offset-rotate:auto;opacity:0}

/* ---------- the type ---------- */
.run .title{animation:wipe 1.2s cubic-bezier(.2,.7,.2,1) var(--t-title) both}
@keyframes wipe{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
.run .rule{animation:grow .8s cubic-bezier(.2,.7,.2,1) var(--t-rule) both}
@keyframes grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.run .titleWrap{animation:titleHome 1.1s cubic-bezier(.3,0,.2,1) var(--t-title-up) both}
@keyframes titleHome{
  from{transform:translate(var(--tdx,340px),var(--tdy,176px)) scale(var(--tsc,2.15))}
  to{transform:translate(0,0) scale(1)}
}
.run .stand{animation:softsub .9s ease-out var(--t-stand) both,
                      subHome 1.1s cubic-bezier(.3,0,.2,1) var(--t-title-up) forwards}
@keyframes softsub{from{opacity:0}to{opacity:.8}}
@keyframes subHome{
  from{transform:translate(var(--sdx,300px),var(--sdy,200px)) scale(var(--ssc,1.6))}
  to{transform:translate(0,0) scale(1)}
}
.run .hatch{animation:soft 1.6s ease-out var(--t-hatch) both}
.run .ground{animation:soft 1.2s ease-out var(--t-ground) both}
.run .vessels{animation:soft .8s ease-out var(--t-glass-in) both}
@keyframes soft{from{opacity:0}to{opacity:1}}

/* ---------- the glass is carried in and set down ---------- */
.run .glassRig{animation:bringGlass 1.4s cubic-bezier(.25,.7,.25,1) var(--t-glass-in) both}
@keyframes bringGlass{
  0%{transform:translate(-780px,26px) rotate(-5deg)}
  62%{transform:translate(-72px,7px) rotate(-1.4deg)}
  84%{transform:translate(14px,-3px) rotate(.6deg)}
  94%{transform:translate(-4px,1px) rotate(-.2deg)}
  100%{transform:translate(0,0) rotate(0deg)}
}
.run .hand3{animation:letGoGlass .8s cubic-bezier(.4,0,.7,.2) var(--t-glass-letgo) both}
@keyframes letGoGlass{
  from{opacity:1;transform:none}
  to{opacity:0;transform:translate(-300px,30px)}
}

/* ---------- the bottle is carried in, tipped, and set back down ----------
   One element, three moves, so the hand never lets go of the bottle. */
.run .rig{
  animation:carryIn 1.8s cubic-bezier(.25,.7,.25,1) var(--t-bottle-in) both,
            tilt 1.0s cubic-bezier(.4,0,.2,1) var(--t-tilt) forwards,
            untilt 1.1s cubic-bezier(.3,0,.2,1) var(--t-untilt) forwards;
}
@keyframes carryIn{
  0%{opacity:0;transform:translate(560px,-190px) rotate(-76deg)}
  5%{opacity:1}
  58%{opacity:1;transform:translate(74px,-26px) rotate(-13deg)}
  78%{transform:translate(-12px,6px) rotate(3.4deg)}
  90%{transform:translate(5px,-2px) rotate(-1.2deg)}
  100%{opacity:1;transform:translate(0,0) rotate(0deg)}
}
/* It goes over far enough to pour and no further. Steeper looked like someone
   emptying a bottle down a sink; this puts the mouth just above the rim, which
   is where it is when a person pours a glass. The pour's spine starts on the
   mouth this leaves, so the two move together; see POUR_SPINE in art.js. */
@keyframes tilt{
  0%{transform:translate(0,0) rotate(0deg)}
  14%{transform:translate(-6px,10px) rotate(4deg)}
  72%{transform:translate(-18px,-78px) rotate(-42deg)}
  88%{transform:translate(-11px,-66px) rotate(-36.4deg)}
  100%{transform:translate(-14px,-70px) rotate(-38deg)}
}
/* the bottle comes back down and lands, rather than gliding into place */
@keyframes untilt{
  0%{transform:translate(-14px,-70px) rotate(-38deg)}
  20%{transform:translate(-18px,-82px) rotate(-42deg)}
  70%{transform:translate(-3px,6px) rotate(2.6deg)}
  82%{transform:translate(2px,-9px) rotate(-1.4deg)}
  92%{transform:translate(0,2px) rotate(.5deg) scaleY(.99)}
  100%{transform:translate(0,0) rotate(0deg)}
}

/* ---------- the cork comes out ---------- */
.run .screw{
  animation:screwDown 1.0s cubic-bezier(.4,0,.4,1) var(--t-screw-down) both,
            screwPull 1.1s cubic-bezier(.5,0,.2,1) var(--t-screw-pull) forwards,
            screwOut .8s cubic-bezier(.5,0,.8,.2) var(--t-screw-out) forwards;
}
@keyframes screwDown{
  from{opacity:0;transform:translateY(-120px)}
  18%{opacity:1}
  to{opacity:1;transform:translateY(0)}
}
@keyframes screwPull{
  0%{transform:translateY(0)}
  50%{transform:translateY(-38px)}
  62%{transform:translateY(-40px)}
  100%{transform:translateY(-78px)}
}
@keyframes screwOut{from{transform:translateY(-78px)}to{transform:translateY(-420px)}}

.run .hand2{animation:reachIn .8s cubic-bezier(.2,.8,.3,1) var(--t-reach) both}
@keyframes reachIn{
  from{opacity:0;transform:translate(150px,-130px)}
  to{opacity:1;transform:none}
}
.run .cork{
  animation:screwPull 1.1s cubic-bezier(.5,0,.2,1) var(--t-screw-pull) both,
            screwOut .8s cubic-bezier(.5,0,.8,.2) var(--t-screw-out) forwards;
}
/* the coil turns as it drives in and again as it lifts */
.run .coil{animation:turn 1.0s linear var(--t-screw-down) both,
                     turn2 1.1s linear var(--t-screw-pull) forwards}
@keyframes turn{from{stroke-dashoffset:0}to{stroke-dashoffset:-96}}
@keyframes turn2{from{stroke-dashoffset:-96}to{stroke-dashoffset:-176}}
.run .handle{animation:spin .3s linear var(--t-screw-down) 3 both,
                       spin .34s linear var(--t-screw-pull) 3 forwards}
@keyframes spin{0%{transform:scaleX(1)}50%{transform:scaleX(.2)}100%{transform:scaleX(1)}}

/* ---------- the pour ----------
   Two things happen at once. The mask draws the stream down its own curve, so
   the wine travels rather than fades in. And the ribbon itself morphs between
   real shapes: a trickle as it opens, a full stream tapering from sixteen to
   eight, and a fractionally different one it breathes between while it runs.
   Both shapes come from one sampler in art.js, so they share a command
   structure and the browser can interpolate the geometry directly. No stroke
   width is being animated anywhere here. */
.run .maskPath{animation:streamDraw .48s cubic-bezier(.45,0,.6,1) var(--t-pour) both,
                         streamUndraw .6s ease-out var(--t-pour-stop) forwards}
@keyframes streamDraw{from{stroke-dashoffset:410}to{stroke-dashoffset:0}}
@keyframes streamUndraw{from{stroke-dashoffset:0}to{stroke-dashoffset:410}}

/* Four states, in order: the trickle it leaves the mouth as, the moment it
   lands in an empty glass and runs round the inside of it, the stream while it
   pours, and the thinner one it tails off to. The curl is not a shape of its
   own: every state is the same ribbon on the same spine, and what changes is
   how far along that spine the wine has got. */
.run .flow{animation:pourHit .3s cubic-bezier(.2,.8,.3,1) var(--t-impact) both,
                     pourRun .4s cubic-bezier(.4,0,.3,1) var(--t-pour-mid) forwards,
                     pourEbb .45s ease-in-out var(--t-pour-thin) forwards,
                     pourShut .5s ease-in var(--t-pour-stop) forwards}
@keyframes pourHit{from{d:var(--pour-start)}to{d:var(--pour-hit)}}
@keyframes pourRun{from{d:var(--pour-hit)}to{d:var(--pour-run)}}
@keyframes pourEbb{from{d:var(--pour-run)}to{d:var(--pour-thin)}}
@keyframes pourShut{from{d:var(--pour-thin)}to{d:var(--pour-start)}}

.run .lip{animation:lipHit .3s cubic-bezier(.2,.8,.3,1) var(--t-impact) both,
                    lipRun .4s cubic-bezier(.4,0,.3,1) var(--t-pour-mid) forwards,
                    lipEbb .45s ease-in-out var(--t-pour-thin) forwards,
                    lipShut .5s ease-in var(--t-pour-stop) forwards}
@keyframes lipHit{from{d:var(--lip-start)}to{d:var(--lip-hit)}}
@keyframes lipRun{from{d:var(--lip-hit)}to{d:var(--lip-run)}}
@keyframes lipEbb{from{d:var(--lip-run)}to{d:var(--lip-thin)}}
@keyframes lipShut{from{d:var(--lip-thin)}to{d:var(--lip-start)}}

/* The glass fills fastest at the start, because the bowl is narrowest at the
   stem and the same volume of wine climbs further down there; it slows as the
   bowl widens. Then one splash comes over the rim, the surface overshoots once
   and damps, and it holds still while the agenda writes in. One wobble: three
   reads as cartoon. */
.run .level{
  animation:fill 2.2s cubic-bezier(.12,.72,.4,1) var(--t-fill) both,
            slosh 1.25s cubic-bezier(.25,.6,.3,1) var(--t-slosh) forwards;
}
@keyframes fill{from{transform:translateY(104px)}to{transform:translateY(0)}}
/* And then it stops rocking: the surface goes flat, because a glass that keeps
   a wave in it for the rest of the slide reads as frozen mid-slosh. */
.run .pool{animation:poolFlat .9s cubic-bezier(.3,0,.3,1) var(--t-settle) forwards}
.run .surf{animation:surfFlat .9s cubic-bezier(.3,0,.3,1) var(--t-settle) forwards}
@keyframes poolFlat{from{d:var(--wine-wave)}to{d:var(--wine-flat)}}
@keyframes surfFlat{from{d:var(--surf-wave)}to{d:var(--surf-flat)}}
@keyframes slosh{
  0%{transform:rotate(0deg)}
  24%{transform:rotate(-4.4deg)}
  58%{transform:rotate(1.4deg)}
  82%{transform:rotate(-.35deg)}
  100%{transform:rotate(0deg)}
}

/* ---------- the splash ----------
   It comes over the rim compact, then reaches out over the paper and thins,
   and the drops leave its tips while it is still going. Both states of every
   arm come from the sampler in art.js and are handed in as custom properties,
   so this only says when: the shapes themselves are geometry, and the d
   property interpolates between them because they share a command structure. */
.swirl{transform-origin:628px 318px}
.run .swirl{animation:swirlIn .3s cubic-bezier(.2,.85,.3,1) var(--t-swirl) both,
                      swirlGone .6s ease-out var(--t-swirl-out) forwards}
@keyframes swirlIn{
  from{opacity:0;transform:translate(10px,26px) scale(.4)}
  to{opacity:1;transform:none}
}
@keyframes swirlGone{from{opacity:1}to{opacity:0}}

.run .sp{animation-duration:.62s;animation-timing-function:cubic-bezier(.25,.72,.3,1);
         animation-delay:var(--t-splash-out);animation-fill-mode:both}
.run .s0{animation-name:sp0}
.run .s1{animation-name:sp1}
.run .s2{animation-name:sp2}
@keyframes sp0{from{d:var(--sp0a)}to{d:var(--sp0b)}}
@keyframes sp1{from{d:var(--sp1a)}to{d:var(--sp1b)}}
@keyframes sp2{from{d:var(--sp2a)}to{d:var(--sp2b)}}

/* ---------- the drops become the agenda ---------- */
.run .drop{animation:fall var(--d-drop) cubic-bezier(.3,0,.7,.6) both}
.run .d1{animation-delay:var(--t-drop1)}
.run .d2{animation-delay:var(--t-drop2)}
.run .d3{animation-delay:var(--t-drop3)}
.run .d4{animation-delay:var(--t-drop4)}
.run .d5{animation-delay:var(--t-drop5)}
@keyframes fall{
  0%{opacity:0;offset-distance:0%}
  10%{opacity:1}
  100%{opacity:1;offset-distance:100%}
}
/* The five lines are not on the clock: each one is revealed by a press, so the
   agenda arrives at the speed it is being talked through. */
.item.on{animation:itemIn .7s cubic-bezier(.2,.8,.3,1) both}
@keyframes itemIn{
  from{opacity:0;transform:translateX(-16px)}
  to{opacity:1;transform:none}
}

/* ---------- leaving: the bottle is hefted and the wine washes across ---------- */
.intro-art.out .rig{animation:heft .72s cubic-bezier(.35,0,.9,1) both}
@keyframes heft{
  0%{transform:none}
  40%{transform:translateY(-112px) rotate(-4deg)}
  54%{transform:translateY(-104px) rotate(-3deg)}
  76%{transform:translateY(8px) rotate(0deg)}
  86%{transform:translateY(0) scaleY(.982)}
  100%{transform:none}
}
/* The out rules replace the animation shorthand .run set, and .vessels is
   opacity:0 until soft brings it in, so it has to be held open here or the
   glass blinks out the moment the wash starts. */
.intro-art.out .vessels{opacity:1;animation:jolt .55s cubic-bezier(.2,.8,.3,1) .54s both}
@keyframes jolt{
  0%{transform:none}
  26%{transform:translateY(-16px) rotate(-2deg)}
  54%{transform:translateY(0) rotate(0deg)}
  76%{transform:translateY(-6px)}
  100%{transform:none}
}

/* ---------- still frame ----------
   No hands, no corkscrew, no flight: the finished tableau, straight away. */
@media (prefers-reduced-motion:reduce){
  .intro-art *{animation:none!important}
  .hand,.hand2,.hand3,.screw{display:none}
  .title{clip-path:none}
  .rule{transform:scaleX(1)}
  .stand{opacity:.8}
  .item.on{opacity:1}
  .hatch,.ground,.vessels{opacity:1}
  .titleWrap,.stand,.glassRig,.rig,.level{transform:none}
  .swirl,.stream{display:none}
  .drop{offset-distance:100%;opacity:1}
}

/* ---------- the orchard the deck opens on ----------
   Two vines draw themselves up the edges, leaves pop along the branches, the
   fruit hangs, both trees are shaken in opposite directions and the fruit rains
   down and bounces once. Each limb, leaf and berry carries its own offset from
   these four starts as a calc() in orchard.js, so the stagger rides on BEATS
   rather than being welded to the clock.

   Both fades end in visibility:hidden rather than opacity:0. A hundred-odd
   filtered nodes left in the layer tree get composited under the pour for the
   rest of the sequence, which is what made it stutter. */
.opener{opacity:0}
.run .opener{animation:soft .35s ease-out var(--t-limbs) both}
.limb{stroke-dasharray:1;stroke-dashoffset:1}
.run .limb{animation:draw .85s cubic-bezier(.35,.05,.3,1) both}
@keyframes draw{to{stroke-dashoffset:0}}
.tleaf{transform-box:fill-box;transform-origin:50% 100%;opacity:0}
.run .tleaf{animation:leafPop .5s cubic-bezier(.2,.8,.3,1) both}
@keyframes leafPop{
  0%{opacity:0;transform:scale(.05) rotate(-16deg)}
  62%{opacity:1;transform:scale(1.08) rotate(3deg)}
  100%{opacity:1;transform:scale(1) rotate(0deg)}
}
.shakeL{transform-origin:56px 706px}
.shakeR{transform-origin:1224px 706px}
.run .shakeL{animation:shakeL .78s ease-in-out var(--t-shake) both}
.run .shakeR{animation:shakeR .78s ease-in-out var(--t-shake) both}
@keyframes shakeL{0%{transform:rotate(0)}14%{transform:rotate(2.4deg)}34%{transform:rotate(-2deg)}54%{transform:rotate(1.4deg)}76%{transform:rotate(-.8deg)}100%{transform:rotate(0)}}
@keyframes shakeR{0%{transform:rotate(0)}14%{transform:rotate(-2.4deg)}34%{transform:rotate(2deg)}54%{transform:rotate(-1.4deg)}76%{transform:rotate(.8deg)}100%{transform:rotate(0)}}
.gb{opacity:0}
.run .gb{animation:gbIn .36s cubic-bezier(.2,.8,.3,1) var(--gd) both,
                   gbFall var(--fd) cubic-bezier(.45,0,.75,1) var(--sd) forwards}
@keyframes gbIn{0%{opacity:0;transform:scale(.1)}70%{opacity:1;transform:scale(1.12)}100%{opacity:1;transform:scale(1)}}
@keyframes gbFall{
  0%{transform:translate(0,0) rotate(0)}
  76%{transform:translate(calc(var(--fx) * .88),var(--fy)) rotate(var(--rot))}
  86%{transform:translate(calc(var(--fx) * .94),calc(var(--fy) - 12px)) rotate(var(--rot))}
  100%{transform:translate(var(--fx),var(--fy)) rotate(var(--rot))}
}
.run .treeArt{animation:fadeGone .7s ease-out var(--t-trees-out) forwards}
.run .grapes{animation:fadeGone .6s ease-out var(--t-fruit-out) forwards}
@keyframes fadeGone{to{opacity:0;visibility:hidden}}
/* the two heavy rigs get their own layer, so the pour is not recompositing the
   orchard underneath it */
.glassRig,.rig{will-change:transform}
@media (prefers-reduced-motion:reduce){.opener{display:none}}
