/* Joybreak motion (lab). Each effect is switched on by a class on <html>, set by the small script in index.html:
   m-slap    hero intro: photos drop in and the headline strips slap down like stickers
   m-boil    hand-drawn doodles that never sit still, a spinning starburst, rocking glasses, a beating heart
   m-pop     sections pop in once as they scroll into view
   m-deal    gallery polaroids get dealt onto the table; they wiggle when you hover them
   m-tap     tap or click any empty spot for a doodle burst; buttons squish when pressed
   m-ticker  a ticker tape of Joybreak things between "What to expect" and the gallery
   m-wobble  the JOYBREAK letters wobble one after another on hover (or tap on phones)
   m-confetti a burst of doodles flies out of the RSVP buttons, just before Meetup opens
   .motion is only added when the visitor has not asked for reduced motion, so none of this runs for them.
   Only transforms (translate, rotate, scale), opacity, and clip-path are animated. Loops pause offscreen (motion.js). */

@property --enter { syntax: "*"; inherits: false; }
@property --idle { syntax: "*"; inherits: false; }

:root { --spring: cubic-bezier(.34, 1.56, .64, 1); --out: cubic-bezier(.22, 1, .36, 1); }

.motion :is(.photo, .strip, .hero-title, .lede, .btn, .proof, .deco, .cheers-art, .splat-wrap, .tag, .gallery-intro, .snap, .paper, .how-title, .num, .step-tag) {
  animation: var(--enter, none), var(--idle, none);
}
.icon { transform-origin: 0 0; }

@keyframes jb-slap { 0% { opacity: 0; scale: 1.7; rotate: -9deg; } 55% { opacity: 1; scale: .94; rotate: 2deg; } 78% { scale: 1.03; rotate: -.5deg; } 100% { opacity: 1; scale: 1; rotate: 0deg; } }
@keyframes jb-drop { 0% { opacity: 0; translate: 0 -70px; rotate: 7deg; } 65% { opacity: 1; translate: 0 6px; rotate: -1.2deg; } 100% { opacity: 1; translate: 0 0; rotate: 0deg; } }
@keyframes jb-tag { 0% { opacity: 0; translate: 0 -26px; rotate: 7deg; } 70% { opacity: 1; translate: 0 3px; rotate: -1deg; } 100% { opacity: 1; translate: 0 0; rotate: 0deg; } }
@keyframes jb-rise { 0% { opacity: 0; translate: 0 22px; } 100% { opacity: 1; translate: 0 0; } }
@keyframes jb-pop { 0% { opacity: 0; scale: 0; rotate: -25deg; } 65% { opacity: 1; scale: 1.14; rotate: 5deg; } 100% { opacity: 1; scale: 1; rotate: 0deg; } }
@keyframes jb-draw { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes jb-thud { 0%, 100% { translate: 0 0; } 25% { translate: 0 4px; } 50% { translate: -2px -1px; } 75% { translate: 1px 1px; } }
@keyframes jb-boil { 0% { translate: 0 0; rotate: 0deg; scale: 1; } 25% { translate: .6px -.8px; rotate: 1.8deg; scale: 1.03; } 50% { translate: -.7px .4px; rotate: -1.4deg; scale: .98; } 75% { translate: .4px .7px; rotate: .8deg; scale: 1.02; } 100% { translate: 0 0; rotate: 0deg; scale: 1; } }
@keyframes jb-spin { to { rotate: 360deg; } }
@keyframes jb-rock { 0%, 100% { rotate: 0deg; } 25% { rotate: -3deg; } 75% { rotate: 3deg; } }
@keyframes jb-beat { 0%, 60%, 100% { scale: 1; } 15% { scale: 1.3; } 30% { scale: .95; } 45% { scale: 1.15; } }
@keyframes jb-clink { 0% { opacity: 0; translate: 40px 30px; rotate: 16deg; } 55% { opacity: 1; translate: 0 0; rotate: -6deg; } 75% { rotate: 3deg; } 100% { opacity: 1; translate: 0 0; rotate: 0deg; } }
@keyframes jb-deal { 0% { opacity: 0; translate: 0 90px; rotate: var(--toss, 12deg); scale: .8; } 60% { opacity: 1; } 100% { opacity: 1; translate: 0 0; rotate: 0deg; scale: 1; } }
@keyframes jb-wiggle { 0%, 100% { rotate: 0deg; } 25% { rotate: -3deg; } 50% { rotate: 2.5deg; } 75% { rotate: -1.5deg; } }
@keyframes jb-ticker { to { translate: -50% 0; } }
@keyframes jb-dot { 0% { opacity: 1; scale: .2; } 70% { opacity: 1; } 100% { opacity: 0; scale: 1.7; } }
@keyframes jb-ray { 0% { opacity: 0; transform: translateY(14px) scaleY(.4); } 25% { opacity: 1; } 100% { opacity: 0; transform: translateY(-12px) scaleY(1); } }

/* 1. Sticker-slap intro (hero) */
.motion.m-slap .photo-main { --enter: jb-drop .75s var(--out) .05s both; }
.motion.m-slap .photo-second { --enter: jb-drop .75s var(--out) .22s both; }
.motion.m-slap .strip-take { --enter: jb-slap .5s var(--out) .32s both; }
.motion.m-slap .strip-mark { --enter: jb-slap .55s var(--out) .5s both; }
.motion.m-slap .strip-today { --enter: jb-slap .5s var(--out) .7s both; }
.motion.m-slap .hero-title { --enter: jb-thud .26s linear .78s; }
.motion.m-slap .hero :is(.burst-h1, .burst-h2, .burst-h3, .crown-hero, .burst-cta-l, .burst-cta-r) { --enter: jb-pop .45s var(--spring) var(--d, 1s) both; }
.hero .burst-h1 { --d: .92s; }
.hero .burst-h2 { --d: 1s; }
.hero .burst-h3 { --d: 1.08s; }
.hero .crown-hero { --d: 1.12s; }
.hero .burst-cta-l { --d: 1.2s; }
.hero .burst-cta-r { --d: 1.28s; }
.motion.m-slap .cheers-art { --enter: jb-pop .6s var(--spring) .95s both; }
.motion.m-slap .lede { --enter: jb-rise .5s var(--out) .9s both; }
.motion.m-slap .btn-dark.btn-block { --enter: jb-rise .5s var(--out) 1s both; }
.motion.m-slap .btn-light.btn-block { --enter: jb-rise .5s var(--out) 1.08s both; }
.motion.m-slap .proof { --enter: jb-rise .5s var(--out) 1.16s both; }
.motion.m-slap .squiggle-hero { --enter: jb-draw .6s ease-out 1.25s both; }

/* 2. Doodles that never sit still */
.motion.m-boil :is(.burst, .crown-hero, .zigzag-gallery, .zigzag-how-tr, .zigzag-how-bl, .squiggle-hero, .swash-pink, .swash-blue-how, .zigzag-orange) { --idle: jb-boil var(--bt, .55s) steps(1, end) var(--bd, 0s) infinite; }
.motion.m-boil .burst:nth-child(3n) { --bt: .45s; }
.motion.m-boil .burst:nth-child(3n + 1) { --bt: .7s; }
.motion.m-boil .splat { --idle: jb-boil 1.1s steps(1, end) infinite; }
.motion.m-boil .starburst { --idle: jb-spin 26s linear infinite; }
.motion.m-boil .cheers-hands { transform-origin: 50% 90%; --idle: jb-rock 2.6s ease-in-out var(--bd, 0s) infinite; }
.motion.m-boil .martini { transform-origin: 50% 95%; --idle: jb-rock 3.2s ease-in-out var(--bd, 0s) infinite; }
.motion.m-boil .heart { --idle: jb-beat 1.5s ease-in-out var(--bd, 0s) infinite; }
.motion.m-boil .hero .deco { --bd: 1.6s; }
.motion.m-boil .closing .deco { --bd: 1.1s; }

/* 3. Sections pop in as they scroll into view */
.motion.m-pop .section-title:not(.is-in) .strip,
.motion.m-pop .expect-grid li:not(.is-in) :is(.splat-wrap, .tag),
.motion.m-pop .gallery-intro:not(.is-in),
.motion.m-pop .paper:not(.is-in),
.motion.m-pop .closing-copy:not(.is-in) :is(.strip, .deco, .btn),
.motion.m-pop .closing-art:not(.is-in) .deco { opacity: 0; }
.motion.m-pop .how:not(:has(.paper.is-in)) :is(.swash-pink, .swash-blue-how) { clip-path: inset(0 100% 0 0); }
.motion.m-pop .section-title.is-in .strip { --enter: jb-slap .5s var(--out) both; }
.expect-grid li:nth-child(2) { --d: .09s; }
.expect-grid li:nth-child(3) { --d: .18s; }
.expect-grid li:nth-child(4) { --d: .27s; }
.motion.m-pop .expect-grid li.is-in .splat-wrap { --enter: jb-pop .6s var(--spring) var(--d, 0s) both; }
.motion.m-pop .expect-grid li.is-in .icon { --enter: jb-pop .5s var(--spring) calc(var(--d, 0s) + .18s) both; }
.motion.m-pop .expect-grid li.is-in .tag { --enter: jb-tag .45s var(--out) calc(var(--d, 0s) + .25s) both; }
.motion.m-pop .gallery-intro.is-in { --enter: jb-rise .55s var(--out) both; }
.steps li:nth-child(1) { --d: .35s; }
.steps li:nth-child(2) { --d: .75s; }
.steps li:nth-child(3) { --d: 1.15s; }
.motion.m-pop .paper.is-in { --enter: jb-rise .5s var(--out) both; }
.motion.m-pop .paper.is-in .how-title { --enter: jb-slap .5s var(--out) .15s both; }
.motion.m-pop .paper.is-in .num { --enter: jb-pop .5s var(--spring) var(--d) both; }
.motion.m-pop .paper.is-in .step-icon { --enter: jb-pop .5s var(--spring) calc(var(--d) + .12s) both; }
.motion.m-pop .paper.is-in .step-tag { --enter: jb-rise .45s var(--out) calc(var(--d) + .2s) both; }
.motion.m-pop .paper.is-in .steps li::after { animation: jb-draw .4s ease-out calc(var(--d) + .3s) both; }
.motion.m-pop .how:has(.paper.is-in) :is(.swash-pink, .swash-blue-how) { --enter: jb-draw .5s ease-out .5s both; }
.motion.m-pop .closing-copy.is-in .strip-close-a { --enter: jb-slap .5s var(--out) both; }
.motion.m-pop .closing-copy.is-in .strip-close-b { --enter: jb-slap .5s var(--out) .16s both; }
.motion.m-pop .closing-copy.is-in .btn-wide { --enter: jb-rise .5s var(--out) .35s both; }
.motion.m-pop .closing-copy.is-in :is(.burst-close, .heart, .burst-close-cta) { --enter: jb-pop .45s var(--spring) .45s both; }
.motion.m-pop .closing-art.is-in .martini { --enter: jb-clink .8s var(--out) .1s both; }
.motion.m-pop .closing-art.is-in .zigzag-orange { --enter: jb-draw .6s ease-out .3s both; }
.motion.m-pop .closing-art.is-in .burst-martini { --enter: jb-pop .45s var(--spring) .7s both; }

/* 4. Polaroids dealt onto the table */
.snap:nth-child(odd) { --toss: 16deg; }
.snap:nth-child(even) { --toss: -14deg; }
.snap:nth-child(4n + 2) { --d: .08s; }
.snap:nth-child(4n + 3) { --d: .16s; }
.snap:nth-child(4n + 4) { --d: .24s; }
.motion.m-deal .snap:not(.is-in) { opacity: 0; }
.motion.m-deal .snap.is-in { --enter: jb-deal .8s var(--out) var(--d, 0s) both; }
.motion.m-deal .snap figure:hover { animation: jb-wiggle .45s ease-in-out; }

/* 5. Tap bursts and squishy buttons */
.tap-burst { position: fixed; z-index: 60; width: 0; height: 0; pointer-events: none; rotate: var(--r, 0deg); }
.tap-burst b { position: absolute; left: -9px; top: -9px; width: 18px; height: 18px; border-radius: 50%; background: var(--c); animation: jb-dot .55s var(--out) both; }
.tap-burst i { position: absolute; left: -3px; top: -34px; width: 6px; height: 16px; border-radius: 3px; background: var(--ink); transform-origin: 3px 34px; rotate: calc(var(--k) * 51.43deg); animation: jb-ray .5s var(--out) both; }
.motion.m-tap .btn { transition: transform .15s ease, box-shadow .15s ease, scale .12s ease; }
.motion.m-tap .btn:active { scale: .94; }

/* 6. Ticker tape */
.ticker { display: none; }
.m-ticker .ticker { display: block; position: relative; z-index: 2; width: 104%; margin: 56px -2% 0; padding: 12px 0 9px; overflow: hidden; background: var(--paper); rotate: -1.6deg; clip-path: polygon(0.00% 8.57%, 1.00% 8.49%, 2.00% 9.38%, 3.00% 9.78%, 4.00% 11.12%, 5.00% 10.48%, 6.00% 11.41%, 7.00% 10.57%, 8.00% 9.94%, 9.00% 10.31%, 10.00% 12.44%, 11.00% 12.27%, 12.00% 10.82%, 13.00% 9.67%, 14.00% 10.79%, 15.00% 13.85%, 16.00% 12.48%, 17.00% 10.60%, 18.00% 11.74%, 19.00% 9.82%, 20.00% 9.52%, 21.00% 9.30%, 22.00% 8.69%, 23.00% 12.93%, 24.00% 11.80%, 25.00% 9.35%, 26.00% 8.25%, 27.00% 8.22%, 28.00% 9.00%, 29.00% 8.66%, 30.00% 8.13%, 31.00% 7.60%, 32.00% 7.08%, 33.00% 7.69%, 34.00% 6.85%, 35.00% 8.06%, 36.00% 9.10%, 37.00% 8.67%, 38.00% 8.27%, 39.00% 7.87%, 40.00% 7.19%, 41.00% 8.06%, 42.00% 6.76%, 43.00% 6.97%, 44.00% 10.05%, 45.00% 9.23%, 46.00% 9.25%, 47.00% 8.94%, 48.00% 7.71%, 49.00% 7.52%, 50.00% 6.99%, 51.00% 6.38%, 52.00% 7.04%, 53.00% 6.95%, 54.00% 5.59%, 55.00% 6.66%, 56.00% 6.91%, 57.00% 7.22%, 58.00% 5.99%, 59.00% 6.25%, 60.00% 6.44%, 61.00% 7.02%, 62.00% 8.14%, 63.00% 7.17%, 64.00% 7.01%, 65.00% 6.98%, 66.00% 5.39%, 67.00% 5.13%, 68.00% 5.34%, 69.00% 4.67%, 70.00% 4.24%, 71.00% 3.84%, 72.00% 3.32%, 73.00% 4.60%, 74.00% 3.82%, 75.00% 4.76%, 76.00% 4.43%, 77.00% 4.29%, 78.00% 4.34%, 79.00% 5.15%, 80.00% 4.12%, 81.00% 5.13%, 82.00% 4.76%, 83.00% 5.19%, 84.00% 3.93%, 85.00% 2.89%, 86.00% 3.22%, 87.00% 2.38%, 88.00% 2.71%, 89.00% 3.18%, 90.00% 3.03%, 91.00% 3.72%, 92.00% 3.75%, 93.00% 3.99%, 94.00% 3.52%, 95.00% 3.28%, 96.00% 3.05%, 97.00% 1.77%, 98.00% 1.38%, 99.00% 1.61%, 100.00% 0.00%, 99.99% 18.29%, 99.94% 36.57%, 99.92% 54.86%, 99.85% 73.14%, 100.00% 91.43%, 99.00% 89.32%, 98.00% 90.39%, 97.00% 90.84%, 96.00% 91.24%, 95.00% 89.83%, 94.00% 89.13%, 93.00% 90.10%, 92.00% 86.59%, 91.00% 87.58%, 90.00% 88.01%, 89.00% 89.97%, 88.00% 86.41%, 87.00% 87.88%, 86.00% 88.31%, 85.00% 86.64%, 84.00% 87.63%, 83.00% 88.07%, 82.00% 89.91%, 81.00% 90.32%, 80.00% 87.15%, 79.00% 89.23%, 78.00% 89.81%, 77.00% 89.33%, 76.00% 90.79%, 75.00% 88.81%, 74.00% 90.95%, 73.00% 90.15%, 72.00% 87.00%, 71.00% 88.09%, 70.00% 90.48%, 69.00% 90.07%, 68.00% 90.89%, 67.00% 91.34%, 66.00% 87.81%, 65.00% 90.11%, 64.00% 91.51%, 63.00% 92.36%, 62.00% 92.45%, 61.00% 91.46%, 60.00% 91.47%, 59.00% 91.12%, 58.00% 91.46%, 57.00% 92.65%, 56.00% 93.25%, 55.00% 92.46%, 54.00% 93.79%, 53.00% 94.44%, 52.00% 94.24%, 51.00% 94.65%, 50.00% 94.03%, 49.00% 93.77%, 48.00% 93.24%, 47.00% 93.34%, 46.00% 94.40%, 45.00% 93.19%, 44.00% 94.34%, 43.00% 94.62%, 42.00% 93.60%, 41.00% 90.54%, 40.00% 91.62%, 39.00% 92.94%, 38.00% 94.52%, 37.00% 95.14%, 36.00% 94.07%, 35.00% 95.17%, 34.00% 94.31%, 33.00% 95.30%, 32.00% 95.35%, 31.00% 95.62%, 30.00% 94.30%, 29.00% 93.86%, 28.00% 95.06%, 27.00% 95.72%, 26.00% 92.17%, 25.00% 94.41%, 24.00% 94.56%, 23.00% 95.80%, 22.00% 96.59%, 21.00% 95.99%, 20.00% 95.30%, 19.00% 91.63%, 18.00% 93.42%, 17.00% 94.85%, 16.00% 96.12%, 15.00% 97.14%, 14.00% 97.06%, 13.00% 97.69%, 12.00% 97.79%, 11.00% 97.51%, 10.00% 98.16%, 9.00% 97.21%, 8.00% 97.84%, 7.00% 96.86%, 6.00% 95.90%, 5.00% 95.52%, 4.00% 96.16%, 3.00% 95.79%, 2.00% 96.05%, 1.00% 96.31%, 0.00% 100.00%, 0.05% 81.71%, 0.05% 63.43%, 0.07% 45.14%, 0.12% 26.86%); }
.ticker-track { display: flex; width: max-content; }
.motion .ticker-track { animation: jb-ticker 34s linear infinite; }
.ticker-group { display: flex; flex: none; align-items: center; gap: 26px; margin: 0; padding-right: 26px; font-family: var(--display); font-weight: 900; font-stretch: 62%; font-size: 40px; line-height: 1; letter-spacing: -.02em; white-space: nowrap; }
.ticker-group i { flex: none; width: 16px; height: 16px; border-radius: 50%; background: var(--pink); }
.ticker-group i:nth-of-type(4n + 2) { background: var(--blue); }
.ticker-group i:nth-of-type(4n + 3) { background: var(--mint); }
.ticker-group i:nth-of-type(4n + 4) { background: var(--tangerine); }
@media (min-width: 760px) {
  .m-ticker .ticker { margin-top: calc(60 * var(--u)); padding: calc(12 * var(--u)) 0 calc(9 * var(--u)); }
  .ticker-group { gap: calc(28 * var(--u)); padding-right: calc(28 * var(--u)); font-size: calc(48 * var(--u)); }
  .ticker-group i { width: calc(18 * var(--u)); height: calc(18 * var(--u)); }
}

/* 7. Wobbly wordmark: each letter is its own path in index.html (.wm-l, --i is its position) */
@keyframes jb-letter {
  0%, 100% { transform: none; }
  16% { transform: translateY(-10%) rotate(-10deg); }
  36% { transform: translateY(4%) rotate(8deg); }
  56% { transform: translateY(-5%) rotate(-5deg); }
  76% { transform: translateY(1%) rotate(2.5deg); }
}
.wm-l { transform-box: fill-box; transform-origin: 50% 85%; }
.motion.m-wobble :is(.brand:hover, .strip-mark:hover, .wordmark.is-wobbling) .wm-l { animation: jb-letter .75s cubic-bezier(.3, .7, .4, 1) calc(var(--i) * 45ms) both; }

/* 8. RSVP confetti (motion.js builds the pieces and animates them) */
.confetti { position: fixed; z-index: 80; left: 0; top: 0; width: 0; height: 0; pointer-events: none; }
.confetti > span { position: absolute; display: block; will-change: transform, opacity; }
.confetti svg { display: block; width: 100%; height: 100%; overflow: visible; }
a[data-confetti] { -webkit-tap-highlight-color: transparent; }

/* Loops pause while their section is offscreen (motion.js adds .is-off) */
.motion .is-off *, .motion .is-off *::after { animation-play-state: paused; }

/* Motion lab panel: preview deployments and local only, never on joybreak.today */
.motion-lab { position: fixed; right: 12px; bottom: 12px; z-index: 70; width: min(292px, calc(100vw - 24px)); padding: 12px 14px; background: var(--paper); border: 2px solid var(--ink); box-shadow: 5px 5px 0 var(--ink); font-family: var(--body); font-size: 15px; line-height: 1.2; }
.motion-lab-title { margin: 0 0 6px; font-family: var(--display); font-weight: 900; font-stretch: 62%; font-size: 26px; line-height: 1; }
.motion-lab-title span { margin-left: 6px; padding: 2px 6px; background: var(--yellow); font-family: var(--body); font-size: 12px; font-weight: 700; vertical-align: middle; }
.motion-lab label { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-weight: 700; cursor: pointer; }
.motion-lab input { width: 18px; height: 18px; margin: 0; accent-color: var(--ink); }
.motion-lab-actions { display: flex; gap: 8px; margin-top: 8px; }
.motion-lab button { flex: 1; min-height: 36px; border: 2px solid var(--ink); background: var(--ink); color: var(--paper); font: 700 14px var(--body); cursor: pointer; }
.motion-lab button + button { flex: 0 0 auto; padding: 0 12px; background: var(--paper); color: var(--ink); }
.motion-lab.is-min label, .motion-lab.is-min .motion-lab-replay { display: none; }
