@media (prefers-reduced-motion: no-preference) {
  .patty-logo {
    transform-origin: 50% 88%;
  }
  .patty-logo.is-entering {
    animation: patty-logo-bounce 1.45s both;
  }
  @keyframes patty-logo-bounce {
    0% { transform: translateX(calc(-100% - 18px)); }
    26% { transform: translate(-67%, -20%) rotate(-5deg) scale(.9, 1.15); }
    46% { transform: translateX(-39%) scale(1.12, .86); }
    63% { transform: translate(-17%, -13%) rotate(3deg) scale(.89, 1.15); }
    76% { transform: translate(-2%, -5%); }
    79%, 82% { transform: scale(1.32, .62); }
    88% { transform: scale(.87, 1.18); }
    94% { transform: scale(1.06, .93); }
    100% { transform: none; }
  }
}

.patty-actor { display: block; pointer-events: none; transform-origin: 50% 88%; }
.patty-wagon {
  position: absolute;
  width: 83%;
  left: 73%;
  top: 42%;
  height: auto;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .patty-actor.is-fetching { animation: patty-fetch 5.6s both; }
  .is-fetching .patty-wagon { animation: patty-cargo 5.6s both; }
}
@keyframes patty-fetch {
  0%, 100% { transform: none; }
  /* Two hops out, then two back with the prop. Repeat to return it. */
  3%, 65% { transform: scale(1.12, .82); }
  7%, 69% { transform: translate(-19%, -24%) scale(.92, 1.1); }
  11%, 73% { transform: translateX(-46%) scale(1.2, .75); }
  15%, 76% { transform: translate(-88%, -18%) scale(.93, 1.08); }
  20%, 23%, 80%, 83% { transform: translateX(calc(-170% - 20px)); }
  28%, 87% { transform: translate(-90%, -20%) scale(.92, 1.1); }
  32%, 91% { transform: translateX(-43%) scale(1.2, .75); }
  37%, 94% { transform: translate(-17%, -25%) scale(.92, 1.1); }
  42%, 97% { transform: scale(1.24, .70); }
  46%, 99% { transform: scale(.96, 1.05); }
  53% { transform: rotate(3deg); }
  61% { transform: none; }
}
@keyframes patty-cargo {
  0%, 20%, 83%, 100% { visibility: hidden; }
  23%, 80% { visibility: visible; }
  34%, 71% { transform: rotate(-6deg); }
  42%, 65% { transform: rotate(2deg); }
}

/* Samantha flies off past the right edge without widening the page. */
/* Keep off-screen props inside the viewport without clipping the sticky header's children. */
html:has(.patty-actor) { overflow-x: clip; }
@media (max-width: 1050px) {
  .site-header { backdrop-filter: none; }
  .site-header .navlinks.open { z-index: 2; }
}

.patty-chip { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .patty-repair .patty-chip {
    display: block;
    pointer-events: none;
    position: absolute;
    top: 0;
    left: 0;
    /* Scale each dimension by √2 to double the cracked area. */
    width: clamp(186.68px, 28.284vw, 346.48px);
    aspect-ratio: 190 / 115;
    background: url("/assets/art/patty-cracked-glass.svg") top left / contain no-repeat;
    filter: drop-shadow(0 1px 0 #fff6);
    animation: patty-crack 11s both;
  }
  /* Patty works on this side of the cracked glass, so the glue stays in view. */
  .patty-repair .brand { z-index: 1; }
  .patty-actor.is-fetching[data-routine="repair"] { animation: patty-repair 11s both; }
  .patty-repair .is-fetching .patty-wagon {
    left: 58%; top: -6%; width: 80%;
    transform-origin: 70% 80%;
    animation: patty-glue 11s both;
  }
}
/* Bonk the glass, watch it crack, fetch glue, seal it, put the glue away. */
@keyframes patty-repair {
  0%, 15%, 61%, 100% { transform: none; }
  4% { transform: scale(1.12, .84); }
  8% { transform: translateY(-7%) scale(1.3); animation-timing-function: cubic-bezier(.2, 0, .3, 1); }
  9% { transform: translateY(-7%) rotate(-2deg) scale(1.44, 1.24); }
  12% { transform: translateY(2%) scale(.9, 1.07); }
  19% { transform: rotate(-5deg); }
  24% { transform: rotate(4deg); }
  29% { transform: rotate(-3deg) scale(1.03, .97); }
  33% { transform: none; }
  37%, 81% { transform: scale(1.12, .82); }
  39%, 83% { transform: translate(-19%, -24%) scale(.92, 1.1); }
  42%, 85% { transform: translateX(-46%) scale(1.2, .75); }
  44%, 87% { transform: translate(-88%, -18%) scale(.93, 1.08); }
  46%, 48%, 89%, 91% { transform: translateX(calc(-170% - 20px)); }
  51%, 93% { transform: translate(-90%, -20%) scale(.92, 1.1); }
  53%, 95% { transform: translateX(-43%) scale(1.2, .75); }
  55%, 97% { transform: translate(-17%, -25%) scale(.92, 1.1); }
  58%, 99% { transform: scale(1.24, .7); }
  64%, 79% { transform: translateY(-4%) rotate(-6deg); }
  68%, 75% { transform: translateY(-6%) rotate(-8deg) scale(1.03, .97); }
  71% { transform: translateY(-4%) rotate(-5deg); }
}
@keyframes patty-glue {
  0%, 47%, 90%, 100% { visibility: hidden; }
  48%, 89% { visibility: visible; }
  48%, 61%, 80%, 89% { transform: none; }
  64% { transform: rotate(-14deg); }
  66%, 70%, 74% { transform: rotate(-14deg) scale(.86, 1.08); }
  68%, 72%, 76% { transform: rotate(-14deg); }
}
@keyframes patty-crack {
  0%, 8.9%, 81%, 100% { opacity: 0; clip-path: circle(0 at 21% 18%); transform: none; }
  9% { opacity: 1; clip-path: circle(6% at 21% 18%); transform: translate(2px, 1px); animation-timing-function: ease-out; }
  10% { transform: translate(-2px, -1px); }
  11% { transform: translate(1px, 0); }
  12% { clip-path: circle(12% at 21% 18%); transform: none; }
  16% { clip-path: circle(24% at 21% 18%); }
  17% { clip-path: circle(27% at 21% 18%); }
  21% { clip-path: circle(44% at 21% 18%); }
  22% { clip-path: circle(48% at 21% 18%); }
  27% { clip-path: circle(76% at 21% 18%); }
  32%, 64% { opacity: 1; clip-path: circle(120% at 21% 18%); }
  78% { opacity: .85; clip-path: circle(4% at 21% 18%); }
}

@media (prefers-reduced-motion: no-preference) {
  .patty-actor[data-routine="pirouette"] {
    animation: patty-pirouette 4.2s both;
  }
  .patty-actor[data-routine="pirouette"] .patty-wagon {
    width: 83%;
    left: 11%;
    top: 48%;
    animation: patty-tutu 4.2s both;
  }
}
@keyframes patty-pirouette {
  0%, 100% { transform: none; }
  12% { transform: scale(1.14, .78); }
  22% { transform: translateY(-7%) rotate(-7deg) rotateY(0deg) scale(.93, 1.09); }
  65% { transform: translateY(-7%) rotate(-7deg) rotateY(720deg) scale(.93, 1.09); animation-timing-function: ease-out; }
  73% { transform: rotateY(720deg) scale(1.16, .79); }
  86% { transform: rotateY(720deg) rotate(12deg) scaleY(.88); }
  100% { transform: rotateY(720deg); }
}
@keyframes patty-tutu {
  0%, 100% { opacity: 0; }
  12%, 90% { opacity: 1; }
}

@media (prefers-reduced-motion: no-preference) {
  .patty-actor[data-routine="bewitched"] {
    animation: patty-spell 5s both;
  }
  .patty-actor[data-routine="bewitched"]::after {
    content: "";
    position: absolute;
    left: 48.5%;
    top: 58.7%;
    width: 6.5%;
    height: 3.2%;
    border-radius: 50%;
    background: #995831;
    animation: patty-nose 5s both;
  }
  .patty-actor[data-routine="bewitched"] .patty-wagon {
    left: 71%;
    top: 26%;
    width: 86%;
    transform-origin: 20% 72%;
    animation: patty-conjure 5s both;
  }
}
@keyframes patty-spell {
  0%, 26%, 100% { transform: none; }
  39%, 75% { transform: rotate(-5deg); }
}
@keyframes patty-nose {
  0%, 100% { opacity: 0; }
  5%, 90% { opacity: 1; }
  0%, 24%, 75%, 90% { transform: none; }
  8%, 16%, 79% { transform: translateX(-38%) rotate(-13deg); }
  12%, 20%, 85% { transform: translateX(38%) rotate(13deg); }
}
@keyframes patty-conjure {
  0%, 24% { opacity: 0; transform: scale(.12); }
  34% { opacity: 1; transform: translateY(-8%) scale(1.1); }
  49%, 66% { opacity: 1; transform: none; }
  /* She turns toward the open side of the header and flies off it. */
  71% { opacity: 1; transform: translateY(-6%) rotate(-4deg); }
  76% { opacity: 1; transform: translateY(-10%) scaleX(-1) rotate(4deg); animation-timing-function: ease-in; }
  100% { opacity: 1; transform: translate(1500%, -70%) scaleX(-1) rotate(10deg); }
}

@media (prefers-reduced-motion: no-preference) {
  .patty-actor[data-routine="frisbee"] {
    animation: patty-pitch 5s both;
  }
  .patty-actor[data-routine="frisbee"] .patty-wagon {
    left: 72%; top: 68%; width: 33%;
    animation: patty-disc 5s both;
  }
  .patty-actor.is-fetching[data-routine="shuffleboard"] { position: relative; animation: patty-hold 20s both; }
  [data-routine="shuffleboard"] .patty-logo { animation: patty-pitch 5s 4 both; }
  .patty-actor[data-routine="shuffleboard"]::before {
    content: ""; position: absolute; left: 54%; top: 75%; width: 34%; height: 4%;
    border: 1px solid #513c2b; border-radius: 3px; background: #e0ae77;
    transform-origin: left; animation: patty-cue 5s 4 both;
  }
  .patty-board {
    position: absolute; left: 80%; top: 43%; width: 125%; height: 48%;
    background: url("/assets/art/patty-shuffleboard.svg?v=triangle") center / 100% 100% no-repeat;
  }
  .patty-board img {
    --target-x: 40%; --target-y: 65%;
    position: absolute; width: 24%; height: 30%;
    transform: translate(-50%, -50%);
    animation: patty-shot 3s 1.2s both;
  }
  .patty-board img:first-child { animation: patty-shot 3s 1.2s both, patty-knockout .55s 8.6s forwards; }
  .patty-board img:nth-child(2) { animation-delay: 6.2s; }
  .patty-board img:nth-child(3) { --target-x: 68%; --target-y: 25%; animation-delay: 11.2s; }
  .patty-board img:nth-child(4) { --target-x: 84%; --target-y: 75%; animation-delay: 16.2s; }
}
@keyframes patty-pitch {
  0%, 100% { transform: none; }
  21% { transform: rotate(-9deg) scale(1.03,.94); }
  32% { transform: rotate(6deg); }
  46%, 85% { transform: none; }
}
@keyframes patty-disc {
  0%, 100% { opacity: 0; transform: scaleY(.5); }
  14%, 25%, 88% { opacity: 1; transform: scaleY(.5); }
  51% { opacity: 1; transform: translate(200%,-150%) rotate(-16deg) scaleY(.40) rotate(360deg); }
  67% { opacity: 1; transform: translate(175%,-110%) rotate(8deg) scaleY(.45) rotate(540deg); }
}
@keyframes patty-shot {
  0% { left: 0%; top: 72%; opacity: 0; }
  10% { left: 0%; top: 72%; opacity: 1; }
  100% { left: var(--target-x); top: var(--target-y); opacity: 1; }
}
@keyframes patty-knockout {
  from { left: 40%; top: 65%; opacity: 1; }
  to { left: 65%; top: 110%; opacity: 0; }
}
@keyframes patty-cue {
  0%, 86%, 100% { opacity: 0; transform: rotate(25deg); }
  18%, 24% { opacity: 1; transform: translateX(-18%) rotate(19deg); }
  32%, 65% { opacity: 1; transform: translateX(17%) rotate(8deg); }
}
/* TV homages. Each one leans on a single prop that nobody has to puzzle over. */
@media (prefers-reduced-motion: no-preference) {
  /* The logo plays its own part, so the actor only keeps time for animationend. */
  .patty-actor.is-fetching[data-routine="brady"] { animation: patty-hold 6.5s both; }
  .patty-actor.is-fetching[data-routine="beam"] { animation: patty-teleport 9s both; }
  .patty-actor.is-fetching[data-routine="jeannie"] { animation: patty-hold 7s both; }
  .patty-actor.is-fetching[data-routine="batman"] { position: relative; animation: patty-biff 6s both; }
  .patty-actor.is-fetching[data-routine="giveaway"] { animation: patty-giveaway 7s both; }
  .patty-actor.is-fetching[data-routine="gilligan"] { animation: patty-voyage 9s both; }

  .patty-actor[data-routine="batman"] .patty-wagon {
    left: 95%; top: 0; width: 300%; margin-top: -78%;
    animation: patty-bursts 6s steps(1, end) both;
  }
  .patty-actor[data-routine="giveaway"] .patty-wagon {
    left: 92%; top: 0; width: 330%; margin-top: -12%;
    animation: patty-bubbles 7s steps(1, end) both;
  }
  .patty-actor[data-routine="beam"] .patty-wagon { left: 0; top: 0; width: 100%; animation: patty-beam 9s both; }
  .patty-actor[data-routine="beam"] .patty-logo { animation: patty-energize 9s both; }
  .patty-actor[data-routine="brady"] .patty-wagon {
    left: 0; top: 0; width: 300%; filter: drop-shadow(3px 4px 0 #2520188c);
    animation: patty-grid 6.5s steps(1, end) both;
  }
  .patty-actor[data-routine="gilligan"] .patty-logo { animation: patty-castaway-costume 9s steps(1, end) both; }
  .patty-actor[data-routine="gilligan"] .patty-wagon {
    left: -18.18%; top: 0; width: 136.36%; transform-origin: 50% 30%;
    animation: patty-castaway 9s both;
  }
  .patty-actor[data-routine="gilligan"]::before {
    content: ""; position: absolute; left: -36.36%; top: 0; width: 181.82%; aspect-ratio: 200 / 150;
    background: url("/assets/art/patty-island.svg") center / contain no-repeat;
    transform-origin: 50% 80%; animation: patty-island 9s both;
  }
  /* Smoke behind Patty, the bottle in front, the twinkle on top. */
  .patty-actor[data-routine="jeannie"] .patty-logo {
    position: relative; z-index: 1; transform-origin: 50% 50%; animation: patty-genie 7s both;
  }
  .patty-actor[data-routine="jeannie"] .patty-wagon {
    left: 25%; top: 0; width: 50%; margin-top: 45%; z-index: 2; transform-origin: 50% 100%;
    animation: patty-bottle 7s both;
  }
  .patty-actor[data-routine="jeannie"]::after {
    content: ""; position: absolute; left: -25%; top: 0; width: 150%; aspect-ratio: 1; margin-top: -25%;
    border-radius: 50%;
    background:
      radial-gradient(circle at 30% 40%, #ff8fc8 0 18%, transparent 19%),
      radial-gradient(circle at 62% 30%, #ff7bbd 0 20%, transparent 21%),
      radial-gradient(circle at 70% 62%, #ff99cf 0 19%, transparent 20%),
      radial-gradient(circle at 38% 68%, #f777b6 0 21%, transparent 22%),
      radial-gradient(circle at 50% 50%, #ffb0da 0 26%, transparent 27%);
    transform-origin: 50% 70%; animation: patty-smoke 7s both;
  }
  .patty-actor[data-routine="jeannie"]::before {
    content: "✦"; position: absolute; left: 64%; top: 0; margin-top: 22%; z-index: 3;
    color: #ffd34d; font: clamp(22px, 2.6vw, 32px)/1 system-ui;
    text-shadow: 0 0 2px #382419, 0 0 8px #fff;
    animation: patty-twinkle 7s both;
  }
}
@keyframes patty-hold { to { transform: none; } }

/* Batman: three punches, three comic-book bursts. */
@keyframes patty-biff {
  0%, 20%, 42%, 68%, 100% { transform: none; }
  10%, 32% { transform: rotate(-8deg) scale(.95, 1.05); }
  14%, 36% { transform: translateX(14%) rotate(10deg) scale(1.15, .9); }
  56% { transform: translateY(-4%) rotate(-10deg) scale(.94, 1.06); }
  60% { transform: translate(16%, -12%) rotate(14deg) scale(1.2, .85); }
  80% { transform: translateY(-8%) scale(.95, 1.05); }
  86% { transform: scale(1.1, .9); }
}
@keyframes patty-bursts {
  0%, 30%, 52%, 82%, 100% { visibility: hidden; transform: none; }
  14% { visibility: visible; clip-path: inset(0 66.67% 0 0); transform: scale(1.18); }
  16% { visibility: visible; clip-path: inset(0 66.67% 0 0); transform: none; }
  36% { visibility: visible; clip-path: inset(0 33.33% 0 33.33%); transform: scale(1.18); }
  38% { visibility: visible; clip-path: inset(0 33.33% 0 33.33%); transform: none; }
  60% { visibility: visible; clip-path: inset(0 0 0 66.67%); transform: scale(1.25); }
  62% { visibility: visible; clip-path: inset(0 0 0 66.67%); transform: none; }
}

/* The giveaway: you get one, you get one, everybody gets one. */
@keyframes patty-giveaway {
  0%, 18%, 42%, 100% { transform: none; }
  6%, 30% { transform: scale(1.1, .88); }
  10% { transform: translateY(-14%) rotate(-10deg) scale(.95, 1.06); }
  34% { transform: translateY(-16%) rotate(10deg) scale(.95, 1.06); }
  14%, 38% { transform: scale(1.12, .86); }
  54% { transform: scale(1.15, .82); }
  60% { transform: translateY(-30%) rotate(-360deg) scale(.94, 1.08); }
  66% { transform: rotate(-360deg) scale(1.2, .8); }
  70%, 82%, 94% { transform: rotate(-360deg); }
  76%, 88% { transform: translateY(-8%) rotate(-360deg); }
}
@keyframes patty-bubbles {
  0%, 92%, 100% { visibility: hidden; transform: none; }
  10% { visibility: visible; clip-path: inset(0 50% 50% 0); transform: scale(1.12); }
  12% { visibility: visible; clip-path: inset(0 50% 50% 0); transform: none; }
  34% { visibility: visible; clip-path: inset(0 0 50% 0); transform: scale(1.12); }
  36% { visibility: visible; clip-path: inset(0 0 50% 0); transform: none; }
  60% { visibility: visible; clip-path: inset(0); transform: scale(1.15); }
  62% { visibility: visible; clip-path: inset(0); transform: none; }
}

/* Star Trek: shimmer out, reappear across the header, then beam home. */
@keyframes patty-teleport {
  0%, 21.9%, 64%, 100% { transform: none; }
  22%, 63.9% { transform: translateX(calc(100vw - 100% - 48px)); }
}
@keyframes patty-energize {
  0%, 6%, 38%, 50%, 82%, 100% { opacity: 1; filter: none; }
  9%, 53% { opacity: .75; filter: brightness(1.5) sepia(.4); }
  12%, 56% { opacity: .95; }
  14%, 58% { opacity: .4; }
  16%, 60% { opacity: .6; }
  18%, 62% { opacity: .15; }
  20%, 26%, 64%, 70% { opacity: 0; filter: brightness(1.8) sepia(.4); }
  28%, 72% { opacity: .2; }
  30%, 74% { opacity: .55; }
  32%, 76% { opacity: .3; }
  34%, 78% { opacity: .8; }
  36%, 80% { opacity: 1; filter: brightness(1.5) sepia(.4); }
}
@keyframes patty-beam {
  0%, 3%, 21%, 25%, 39%, 47%, 65%, 69%, 84%, 100% { opacity: 0; transform: none; }
  7%, 18%, 28%, 36%, 51%, 62%, 72%, 80% { opacity: 1; transform: none; }
  12%, 32%, 56%, 76% { opacity: 1; transform: translateY(-4%); }
}

/* The Brady Bunch: the tiles fill in one Patty at a time. */
@keyframes patty-grid {
  0%, 86%, 100% { visibility: hidden; clip-path: polygon(0 0, 100% 0, 100% 0%, 0% 0%, 0% 0%, 0 0%); }
  4% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 0%, 33.33% 0%, 33.33% 33.33%, 0 33.33%); }
  8% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 0%, 66.67% 0%, 66.67% 33.33%, 0 33.33%); }
  12% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 33.33%, 0% 33.33%, 0% 66.67%, 0 66.67%); }
  16% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 33.33%, 33.33% 33.33%, 33.33% 66.67%, 0 66.67%); }
  20% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 33.33%, 66.67% 33.33%, 66.67% 66.67%, 0 66.67%); }
  24% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 66.67%, 0% 66.67%, 0% 100%, 0 100%); }
  28% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 66.67%, 33.33% 66.67%, 33.33% 100%, 0 100%); }
  32% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 66.67%, 66.67% 66.67%, 66.67% 100%, 0 100%); }
  36% { visibility: visible; clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%, 0% 133.33%, 0 133.33%); }
}

/* Gilligan's Island: off for a three-hour tour, back in a storm, washed up. */
@keyframes patty-voyage {
  0%, 60%, 84%, 96%, 100% { transform: none; }
  3% { transform: scale(1.12, .82); }
  7% { transform: translate(-19%, -24%) scale(.92, 1.1); }
  11% { transform: translateX(-46%) scale(1.2, .75); }
  15% { transform: translate(-88%, -18%) scale(.93, 1.08); }
  19%, 21% { transform: translateX(calc(-170% - 20px)); animation-timing-function: ease-out; }
  30% { transform: none; }
  34% { transform: translateY(-3%) rotate(-6deg); }
  38% { transform: translateY(2%) rotate(8deg); }
  42% { transform: translateY(-5%) rotate(-12deg); }
  46% { transform: translateY(3%) rotate(14deg); }
  50% { transform: translateY(-6%) rotate(-16deg); }
  54% { transform: translateY(2%) rotate(18deg); }
  57% { transform: translate(-6%, -16%) rotate(-30deg); }
  64%, 72%, 80% { transform: rotate(-3deg); }
  68%, 76% { transform: rotate(3deg); }
  88% { transform: scale(1.1, .86); }
  92% { transform: translateY(-10%) scale(.95, 1.05); }
}
@keyframes patty-castaway-costume {
  0%, 95%, 100% { content: normal; }
  20%, 94% { content: url("/assets/art/patty.svg?v=bucket#castaway"); }
}
@keyframes patty-castaway {
  0%, 19.9%, 95%, 100% { visibility: hidden; clip-path: inset(0); transform: none; opacity: 1; }
  20%, 57.9% { visibility: visible; clip-path: inset(0); }
  58%, 90% { visibility: visible; clip-path: inset(0 0 50% 0); transform: none; opacity: 1; }
  94% { visibility: visible; clip-path: inset(0 0 50% 0); transform: translateY(-70%) rotate(-30deg); opacity: 0; }
}
@keyframes patty-island {
  0%, 56%, 100% { opacity: 0; transform: translateY(20%) scale(.4); }
  60% { opacity: 1; transform: scale(1.06); }
  63%, 86% { opacity: 1; transform: none; }
  92% { opacity: 0; transform: translateY(20%); }
}

/* I Dream of Jeannie: into the bottle, out in pink smoke, then the nod and blink. */
@keyframes patty-genie {
  0%, 4%, 100% { opacity: 1; transform: none; }
  8% { transform: scale(1.1, .85); }
  16% { opacity: 1; transform: translateY(5%) rotate(540deg) scale(.08); }
  17%, 33% { opacity: 0; transform: translateY(5%) scale(.08); }
  34% { opacity: 1; transform: translateY(-10%) scale(.15); }
  42% { transform: translateY(-22%) scale(1.08); }
  46%, 52%, 60% { transform: translateY(-20%); }
  54% { transform: translateY(-13%) scale(1.04, .9); }
  57% { transform: translateY(-21%); }
  68%, 84% { transform: translateY(-25%); }
  76% { transform: translateY(-18%); }
  90% { transform: scale(1.08, .9); }
  95% { transform: scale(.96, 1.04); }
}
@keyframes patty-bottle {
  0%, 94%, 100% { opacity: 0; transform: scale(0); }
  6% { opacity: 1; transform: scale(1.15); }
  9%, 18%, 35%, 86% { opacity: 1; transform: none; }
  21% { transform: rotate(-10deg); }
  24% { transform: rotate(10deg); }
  27% { transform: rotate(-14deg); }
  30% { transform: rotate(14deg); }
  32% { transform: scale(1.12, .88); }
}
@keyframes patty-smoke {
  0%, 31%, 60%, 85%, 100% { opacity: 0; transform: scale(.2); }
  34% { opacity: .95; transform: scale(1.1); }
  46% { opacity: .75; transform: scale(1.25); }
  59.9% { opacity: 0; transform: scale(1.4); }
  90% { opacity: .85; transform: translateY(20%) scale(.6); }
}
@keyframes patty-twinkle {
  0%, 54%, 64%, 100% { opacity: 0; transform: scale(0) rotate(0); }
  57% { opacity: 1; transform: scale(1.3) rotate(45deg); }
  61% { opacity: 1; transform: scale(1) rotate(90deg); }
}

/* The showcase: Patty sets the newest pieces out on a row of easels. */
.patty-actor.is-fetching[data-routine="showcase"] { animation: none; }
.patty-showcasing .brand { z-index: 1; }
.patty-showcase {
  position: absolute;
  top: 4px;
  display: flex;
  justify-content: space-evenly;
  pointer-events: none;
}
.patty-easel {
  position: relative;
  width: var(--patty-easel-width, 60px);
  aspect-ratio: 100 / 150;
  background: url("/assets/art/patty-easel.svg") bottom / contain no-repeat;
}
.patty-easel-art {
  position: absolute;
  left: 10%;
  top: 6%;
  width: 80%;
  aspect-ratio: 1;
  object-fit: cover;
  border: 3px solid #6e4a26;
  border-radius: 2px;
  background: #fff;
  box-shadow: 2px 3px 0 #2520188c;
}
