:root {
  --pink: #ff4f9a;
  --pink-dark: #d8336f;
  --pink-soft: #ffd6e8;
  --green: #3fc04f;
  --green-dark: #23933a;
  --blue: #3d7bf0;
  --gold: #ffb81f;
  --ink: #5b2a45;
  --card: #fffaf4;
  --font: 'Baloo 2', 'Trebuchet MS', 'Comic Sans MS', system-ui, sans-serif;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; overflow: hidden; background: #2b1630; font-family: var(--font); color: var(--ink); user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
button { font-family: inherit; color: inherit; border: 0; background: none; padding: 0; cursor: pointer; }

#stage { position: absolute; left: 50%; top: 50%; width: 1600px; height: 900px; transform-origin: center; overflow: hidden; background: #fbe6ef; }
#bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
#scene, #hud { position: absolute; inset: 0; }
#hud { pointer-events: none; z-index: 50; }
#hud > * { pointer-events: auto; }
.sprite { display: block; pointer-events: none; }
.room { position: absolute; inset: 0; }

/* ---------- loader ---------- */
#loader { position: absolute; inset: 0; z-index: 100; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 30px; background: radial-gradient(circle at 50% 40%, #fff1f7, #ffc6df); }
.loader-title { font-size: 72px; font-weight: 800; color: var(--pink); text-shadow: 0 4px 0 #fff; }
.bar { width: 600px; height: 34px; border-radius: 20px; background: #fff; box-shadow: inset 0 3px 6px rgba(0,0,0,.12); overflow: hidden; border: 4px solid #fff; }
.fill { height: 100%; width: 0; background: linear-gradient(90deg, #ff8cc3, var(--pink)); border-radius: 20px; transition: width .2s; }
#rotate { display: none; }
@media (orientation: portrait) and (max-width: 900px) {
  #rotate { display: flex; position: fixed; inset: 0; z-index: 200; align-items: center; justify-content: center; background: #ffd6e8; color: var(--pink-dark); font: 800 28px var(--font); text-align: center; padding: 30px; }
}

/* ---------- HUD ---------- */
.ribbon { position: absolute; left: 24px; top: 18px; padding: 8px 64px 14px 38px; font-size: 46px; font-weight: 800; color: #fff; letter-spacing: .5px;
  background: linear-gradient(#ff6fae, #f0438c); clip-path: polygon(0 0, 100% 0, 94% 50%, 100% 100%, 0 100%, 4% 50%);
  filter: drop-shadow(0 4px 0 rgba(160, 20, 80, .35)); text-shadow: 0 3px 0 rgba(150, 20, 70, .45); display: flex; gap: 14px; align-items: center; pointer-events: none; }
.ribbon .dot { opacity: .85; }
.btn-round { position: absolute; width: 84px; height: 84px; border-radius: 50%; background: #fff; color: var(--pink); box-shadow: 0 6px 0 #f1b6cf, 0 10px 20px rgba(0,0,0,.15); display: grid; place-items: center; }
.btn-round svg { width: 46px; height: 46px; }
.btn-round:active { transform: translateY(4px); box-shadow: 0 2px 0 #f1b6cf; }
.btn-mute { right: 28px; top: 22px; }
.btn-back { left: 28px; bottom: 30px; }

.btn-action { position: absolute; right: 34px; bottom: 30px; display: flex; align-items: center; gap: 14px; padding: 14px 44px 18px 30px; border-radius: 60px;
  font-size: 54px; font-weight: 800; color: #fff; text-shadow: 0 3px 0 rgba(0,0,0,.2); transition: transform .12s, filter .2s, opacity .2s; }
.btn-action .ico { width: 62px; height: 62px; display: grid; place-items: center; }
.btn-action .ico svg { width: 100%; height: 100%; }
.btn-action.ok { background: linear-gradient(#62dc6c, var(--green)); box-shadow: 0 8px 0 var(--green-dark), 0 14px 26px rgba(0,0,0,.2); border: 5px solid #fff; animation: breathe 1.6s ease-in-out infinite; }
.btn-action.ok.disabled { filter: grayscale(.85) brightness(1.05); opacity: .75; animation: none; }
.btn-action.ufle, .btn-action.ver, .btn-action.dans { width: 190px; height: 190px; border-radius: 50%; flex-direction: column; justify-content: center; gap: 0; padding: 0; font-size: 42px; border: 7px solid #fff; animation: breathe 1.4s ease-in-out infinite; }
.btn-action.ufle .ico, .btn-action.ver .ico, .btn-action.dans .ico { width: 92px; height: 92px; }
.btn-action.ufle { background: radial-gradient(circle at 40% 30%, #6fa4ff, var(--blue)); box-shadow: 0 8px 0 #2a59b8, 0 14px 26px rgba(0,0,0,.25); }
.btn-action.ver { background: radial-gradient(circle at 40% 30%, #72e07c, var(--green)); box-shadow: 0 8px 0 var(--green-dark), 0 14px 26px rgba(0,0,0,.25); }
.btn-action.dans { background: radial-gradient(circle at 40% 30%, #ffd45e, var(--gold)); box-shadow: 0 8px 0 #d38a00, 0 14px 26px rgba(0,0,0,.25); }
.btn-action:active { transform: translateY(6px) scale(.97); }
@keyframes breathe { 50% { transform: scale(1.05); } }

.btn-start { padding: 18px 90px 24px; border-radius: 70px; font-size: 76px; font-weight: 800; color: #fff; background: linear-gradient(#ff7cb8, var(--pink)); border: 7px solid #fff;
  box-shadow: 0 10px 0 var(--pink-dark), 0 18px 30px rgba(0,0,0,.25); text-shadow: 0 4px 0 rgba(150,20,70,.4); animation: breathe 1.4s ease-in-out infinite; }
.btn-pill { padding: 14px 40px 18px; border-radius: 50px; font-size: 40px; font-weight: 800; color: #fff; background: linear-gradient(#ff7cb8, var(--pink)); border: 5px solid #fff; box-shadow: 0 7px 0 var(--pink-dark), 0 12px 20px rgba(0,0,0,.2); white-space: nowrap; }
.btn-pill.busy { background: linear-gradient(#ffc06a, #ff9a3c); box-shadow: 0 7px 0 #d06f17; }
.btn-pill:active { transform: translateY(4px); }
.btn-mini { width: 64px; height: 64px; border-radius: 50%; background: #fff; font-size: 44px; font-weight: 800; color: var(--pink); box-shadow: 0 4px 0 #f1b6cf; line-height: 1; }

/* ---------- panels & cards ---------- */
.panel { background: rgba(255, 250, 244, .9); border-radius: 34px; padding: 22px; box-shadow: 0 10px 30px rgba(120, 40, 80, .18), inset 0 0 0 4px #fff; }
.panel.grid { display: grid; gap: 18px; }
.card { position: relative; background: var(--card); border-radius: 26px; box-shadow: 0 5px 0 #ead7cf, 0 8px 16px rgba(0,0,0,.08); display: grid; place-items: center; overflow: hidden; transition: transform .15s, box-shadow .15s; border: 5px solid transparent; }
.card:active { transform: scale(.95); }
.card.on { border-color: var(--pink); box-shadow: 0 5px 0 var(--pink-dark), 0 10px 22px rgba(255, 79, 154, .35); transform: translateY(-4px); }
.card .tick { position: absolute; right: 10px; top: 10px; width: 46px; height: 46px; border-radius: 50%; background: #fff; border: 3px solid #e4d2cc; color: transparent; display: grid; place-items: center; }
.card .tick svg { width: 30px; height: 30px; }
.card.on .tick { background: var(--pink); border-color: #fff; color: #fff; animation: pop .3s; }
.friends .card.on { border-color: var(--green); box-shadow: 0 5px 0 var(--green-dark), 0 10px 22px rgba(63, 192, 79, .35); }
.friends .card.on .tick { background: var(--green); }
.friends .card .tick { width: 54px; height: 54px; }
.card.locked { opacity: .45; filter: grayscale(.6); }
.card-img { max-width: 86%; max-height: 86%; object-fit: contain; }
.card-img.small { max-width: 74%; max-height: 74%; }
.cardbody { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.name { font-size: 30px; font-weight: 800; color: var(--pink-dark); line-height: 1; }
.name.small { font-size: 24px; }
.portrait { border-radius: 22px; background-repeat: no-repeat; }
.framecrop { background-repeat: no-repeat; }
.card.mini { width: 120px; height: 120px; border-radius: 22px; }
.card.mini img { max-width: 90px; max-height: 92px; object-fit: contain; }
.card.mini .tick { width: 34px; height: 34px; right: 6px; top: 6px; }
.card.mini .tick svg { width: 22px; height: 22px; }
.panel-title { font-size: 30px; font-weight: 800; color: var(--pink-dark); margin: 4px 6px 8px; }
.row { display: flex; gap: 14px; margin-bottom: 10px; align-items: center; }

/* ---------- doll ---------- */
.doll { position: relative; }
.doll-inner { position: absolute; inset: 0; transform-origin: 50% 95%; }
.doll-layer { position: absolute; display: block; pointer-events: none; }
.preview { display: flex; justify-content: center; }
.placeholder { width: 420px; height: 600px; margin-top: 80px; border-radius: 40px; border: 8px dashed #f6a8c9; display: grid; place-items: center; font-size: 200px; font-weight: 800; color: #f6a8c9; background: rgba(255,255,255,.5); }
.bday-card { padding: 20px 20px 70px; border-radius: 40px; background: linear-gradient(#ffe2ef, #ffc7de); box-shadow: 0 10px 30px rgba(120,40,80,.2), inset 0 0 0 6px #fff; }
.bday-card .badge { position: absolute; left: 50%; bottom: 18px; translate: -50% 0; background: var(--pink); color: #fff; font-size: 30px; font-weight: 800; padding: 4px 26px 8px; border-radius: 30px; white-space: nowrap; border: 4px solid #fff; }
.counter { display: flex; gap: 10px; font-size: 56px; }
.heart { color: #fff; text-shadow: 0 0 0 #000, 0 3px 6px rgba(0,0,0,.2); -webkit-text-stroke: 3px #f3a8c8; transition: transform .2s; }
.heart.on { color: var(--pink); -webkit-text-stroke: 3px #fff; transform: scale(1.15); }

/* ---------- step specific ---------- */
.toolbar { display: flex; gap: 12px; padding: 16px; }
.tool { position: relative; width: 100px; height: 100px; border-radius: 22px; background: var(--card); display: grid; place-items: center; box-shadow: 0 5px 0 #ead7cf; border: 5px solid transparent; }
.tool img { max-width: 84%; max-height: 84%; object-fit: contain; }
.tool.wide img { width: 84%; height: 70%; max-width: none; object-fit: cover; object-position: 0 50%; }
.tool.on { border-color: var(--pink); box-shadow: 0 5px 0 var(--pink-dark); transform: translateY(-4px); }
.tool .tick { position: absolute; right: 4px; bottom: 4px; width: 30px; height: 30px; border-radius: 50%; background: #fff; border: 3px solid #e4d2cc; color: transparent; display: grid; place-items: center; }
.tool .tick svg { width: 20px; }
.tool.on .tick { background: var(--pink); color: #fff; border-color: #fff; }
.deco { position: absolute; }
.deco.movable { pointer-events: auto; cursor: grab; touch-action: none; transition: filter .15s; }
.deco.movable:hover { filter: drop-shadow(0 0 12px #fff); }
.deco.dragging { cursor: grabbing; filter: drop-shadow(0 12px 14px rgba(0,0,0,.3)); scale: 1.06; }
.hint { padding: 10px 28px 14px; border-radius: 30px; background: rgba(255,255,255,.88); font-size: 28px; font-weight: 800; color: var(--pink-dark); white-space: nowrap; box-shadow: 0 6px 16px rgba(0,0,0,.12); pointer-events: none; }
.hint.big { font-size: 34px; }
.speech { padding: 18px 34px 24px; border-radius: 34px; background: #fff; font-size: 38px; font-weight: 600; white-space: nowrap; box-shadow: 0 8px 20px rgba(0,0,0,.12); }
.speech b { color: var(--pink-dark); }
.guest-tabs { display: flex; gap: 18px; }
.gtab { position: relative; border-radius: 26px; padding: 5px; background: #fff; box-shadow: 0 5px 0 #ead7cf; border: 5px solid transparent; }
.gtab.on { border-color: var(--gold); box-shadow: 0 5px 0 #d38a00, 0 0 0 6px rgba(255, 210, 80, .4); transform: translateY(-4px) scale(1.06); }
.tab-badge { position: absolute; right: -16px; bottom: -14px; width: 66px; filter: drop-shadow(0 3px 3px rgba(0,0,0,.25)); }
.tab-ok { position: absolute; right: -10px; bottom: -10px; width: 46px; height: 46px; border-radius: 50%; background: var(--green); color: #fff; display: grid; place-items: center; border: 4px solid #fff; }
.tab-ok svg { width: 28px; }
.held { filter: drop-shadow(0 8px 10px rgba(0,0,0,.2)); }
.tag { padding: 10px 30px 14px; border-radius: 26px; background: #fff; font-size: 34px; font-weight: 800; color: var(--pink-dark); text-align: center; line-height: 1.1; box-shadow: 0 6px 16px rgba(0,0,0,.12); white-space: nowrap; }
.tag small { font-size: 26px; color: var(--ink); font-weight: 600; }
.giftbox { position: relative; }
.giftbox .sprite { filter: drop-shadow(0 6px 6px rgba(0,0,0,.15)); }
.giftbox .bow { animation: pop .35s; }
.floating { pointer-events: auto !important; cursor: pointer; animation: float 1.6s ease-in-out infinite; filter: drop-shadow(0 12px 10px rgba(0,0,0,.2)); }
.floating.drop { animation: dropIn .55s ease-in forwards; }
@keyframes float { 50% { translate: -50% -14px; } }
@keyframes dropIn { to { translate: -50% 170px; scale: .6; opacity: .2; } }
.wrap-panel { width: 450px; }
.ing-panel { display: grid; grid-template-columns: repeat(2, 170px); gap: 18px; }
.card.ing { width: 170px; height: 170px; touch-action: none; }
.card.ing img { max-width: 130px; max-height: 130px; object-fit: contain; }
.card.ing.used { opacity: .45; filter: grayscale(.4); }
.card.ing.used .tick { background: var(--green); color: #fff; border-color: #fff; }
.ghost { opacity: .9; filter: drop-shadow(0 14px 12px rgba(0,0,0,.3)); translate: -50% -50% !important; }
.bowl { touch-action: none; cursor: grab; }
.bowl img { width: 100%; display: block; filter: drop-shadow(0 16px 14px rgba(80, 30, 40, .25)); }
.spoon { opacity: 0; transition: opacity .3s; filter: drop-shadow(0 8px 8px rgba(0,0,0,.25)); rotate: 20deg; }
.spoon.show { opacity: 1; animation: stirHint 1.6s ease-in-out infinite; }
@keyframes stirHint { 25% { translate: -30% 20px; } 50% { translate: -50% 40px; } 75% { translate: -70% 20px; } }
.progress-ring { width: 150px; height: 150px; transition: opacity .3s; }
.progress-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.progress-ring circle { fill: rgba(255,255,255,.9); stroke-width: 12; }
.progress-ring .bgc { stroke: #f5d8e5; }
.progress-ring .fg { fill: none; stroke: var(--pink); stroke-linecap: round; stroke-dasharray: 264; stroke-dashoffset: 264; transition: stroke-dashoffset .15s; }
.oven { position: absolute; }
.oven img { width: 100%; display: block; }
.oven .oven-baked { position: absolute; left: 0; top: 0; opacity: 0; }
.oven.done .oven-baked { opacity: 1; }
.oven-glow { position: absolute; left: 22%; top: 38%; width: 56%; height: 34%; border-radius: 30px; background: radial-gradient(ellipse, rgba(255, 170, 60, .55), transparent 70%); opacity: 0; pointer-events: none; }
.oven.baking .oven-glow { animation: glow 1s ease-in-out infinite; }
.oven.baking { animation: hum .25s linear infinite; }
@keyframes glow { 50% { opacity: 1; } }
@keyframes hum { 50% { translate: -50% 1px; } }
.timer { width: 280px; height: 280px; filter: drop-shadow(0 10px 16px rgba(0,0,0,.18)); }
.timer svg { width: 100%; height: 100%; }
.timer .face { fill: #fff; stroke: #f3c9d9; stroke-width: 5; }
.timer .wedge { fill: #ff7aa8; }
.timer .hand { stroke: #5b3a46; stroke-width: 5; stroke-linecap: round; }
.deco-panel { width: 480px; }
.swirl { width: 74px; height: 74px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; box-shadow: inset -8px -8px 0 rgba(0,0,0,.08), inset 6px 6px 0 rgba(255,255,255,.6), 0 0 0 4px #fff; }
.candle-count { font-size: 34px; font-weight: 800; color: var(--pink-dark); }
.cake { position: relative; }
.cake-img { width: 100%; display: block; filter: drop-shadow(0 14px 12px rgba(80,30,40,.25)); }
.cake-top { position: absolute; inset: 0; pointer-events: none; }
.cake-item { position: absolute; translate: -50% -88%; }
.cake-item.top { translate: -50% -60%; }
.cake-item img { width: 100%; display: block; filter: drop-shadow(0 2px 2px rgba(0,0,0,.2)); }
.cake-item.candle img { animation: pop .3s; }
.flame { position: absolute; left: 50%; top: -38%; width: 70%; height: 46%; translate: -50% 0; border-radius: 50% 50% 50% 50% / 65% 65% 35% 35%;
  background: radial-gradient(ellipse at 50% 70%, #fff 0 18%, #ffe066 35%, #ff9d2e 65%, transparent 72%); opacity: 0; transform-origin: 50% 100%; transition: opacity .3s; }
.flame.on { opacity: 1; animation: flicker .18s ease-in-out infinite alternate; filter: drop-shadow(0 0 8px #ffcf4d); }
.flame.out { opacity: 0; }
.flame.out::after { content: ''; position: absolute; left: 30%; top: 20%; width: 40%; height: 60%; border-radius: 50%; background: rgba(200,200,200,.7); animation: smoke 1.6s ease-out forwards; }
@keyframes flicker { from { transform: scale(1, 1) rotate(-3deg); } to { transform: scale(.9, 1.1) rotate(3deg); } }
@keyframes smoke { from { opacity: .8; transform: translateY(0) scale(.6); } to { opacity: 0; transform: translateY(-120px) scale(2); } }

/* celebration */
.door-hit { border-radius: 20px; cursor: pointer; }
.door-hit.pulse { animation: doorPulse 1.2s ease-in-out infinite; }
@keyframes doorPulse { 50% { box-shadow: 0 0 0 10px rgba(255, 255, 255, .8), 0 0 40px 20px rgba(255, 210, 90, .7); } }
.arrival.walking .doll-inner { animation: walk .35s ease-in-out infinite alternate; }
@keyframes walk { from { transform: translateY(0) rotate(-3deg); } to { transform: translateY(-14px) rotate(3deg); } }
.host .doll-inner { animation: sway 2.4s ease-in-out infinite; }
.party-table { filter: drop-shadow(0 -6px 10px rgba(0,0,0,.08)); }
.seated.blowing .doll-inner { animation: blowLean 1.3s ease-in-out; }
@keyframes blowLean { 30%, 70% { transform: translateY(18px) scale(1.03, .98); } }
.puff { width: 220px; height: 120px; translate: -50% 0; }
.puff::before, .puff::after { content: ''; position: absolute; left: 50%; top: 0; width: 60px; height: 60px; border-radius: 50%; background: rgba(255,255,255,.85); box-shadow: 30px 30px 0 -6px rgba(255,255,255,.7), -30px 40px 0 -10px rgba(255,255,255,.6); animation: puff 1.1s ease-out forwards; }
.puff::after { animation-delay: .25s; }
@keyframes puff { from { transform: translate(-50%, 0) scale(.3); opacity: 1; } to { transform: translate(-50%, 140px) scale(1.8); opacity: 0; } }
.guest.cheer .doll-inner { animation: cheer .5s ease-in-out 4 alternate; }
@keyframes cheer { to { transform: translateY(-26px); } }
.seated.happy .doll-inner { animation: cheer .4s ease-in-out 6 alternate; }
.slice { cursor: grab; touch-action: none; filter: drop-shadow(0 10px 10px rgba(0,0,0,.25)); }
.slice.grab { pointer-events: auto !important; animation: float 1.4s ease-in-out infinite; }
.hand-hint { width: 90px; height: 90px; pointer-events: none; }
.hand-hint::before { content: '👆'; font-size: 80px; position: absolute; animation: handMove 1.8s ease-in-out infinite; }
@keyframes handMove { 0% { transform: translate(0, 0); opacity: 0; } 15% { opacity: 1; } 80% { transform: translate(-220px, -50px); opacity: 1; } 100% { opacity: 0; } }
.dancer .doll-inner { transform-origin: 50% 90%; }
.dancer.twirl .doll-inner { animation: twirl 1.6s ease-in-out infinite; }
.dancer.hop .doll-inner { animation: hop .5s ease-in-out infinite alternate; }
.dancer.sway .doll-inner { animation: sway .8s ease-in-out infinite; }
.dancer.wiggle-dance .doll-inner { animation: wiggleDance .6s ease-in-out infinite; }
@keyframes twirl { 0% { transform: scaleX(1) translateY(0); } 25% { transform: scaleX(.1) translateY(-30px); } 50% { transform: scaleX(-1) translateY(0); } 75% { transform: scaleX(-.1) translateY(-30px); } 100% { transform: scaleX(1) translateY(0); } }
@keyframes hop { from { transform: translateY(0) scale(1.03, .97); } to { transform: translateY(-60px) scale(.97, 1.04); } }
@keyframes sway { 0%, 100% { transform: rotate(-7deg); } 50% { transform: rotate(7deg); } }
@keyframes wiggleDance { 0%, 100% { transform: rotate(0) translateX(0); } 25% { transform: rotate(-10deg) translateX(-30px) translateY(-20px); } 75% { transform: rotate(10deg) translateX(30px) translateY(-20px); } }
/* friends sway to the music (one sway per 2 beats), then bop on the beat once the dancing starts; game.js keeps the phase locked */
.friend-dancer .doll-inner { animation: sway calc(var(--beat, .484s) * 2) ease-in-out infinite; }
.friend-dancer.bopping .doll-inner { animation: hop var(--beat, .484s) ease-in-out infinite alternate; }
.note { position: absolute; font-size: 64px; font-weight: 800; text-shadow: 0 3px 0 #fff; animation: noteUp 2s ease-out forwards; pointer-events: none; z-index: 15; }
@keyframes noteUp { from { opacity: 0; transform: translateY(0) scale(.6); } 20% { opacity: 1; } to { opacity: 0; transform: translateY(-260px) translateX(40px) scale(1.2) rotate(15deg); } }
.replay { opacity: 0; pointer-events: none; transition: opacity .4s; }
.replay.show { opacity: 1; pointer-events: auto; }

/* title */
.title { margin: 0; text-align: center; font-size: 100px; line-height: .95; font-weight: 800; color: #fff; text-shadow: 0 6px 0 var(--pink-dark), 0 12px 24px rgba(160, 30, 90, .4); -webkit-text-stroke: 3px var(--pink); white-space: nowrap; }
.title span { font-size: 130px; color: #fff3a6; -webkit-text-stroke: 3px #ff8a00; text-shadow: 0 6px 0 #d86b00, 0 12px 24px rgba(160, 80, 0, .4); }
.title-dolls { display: flex; align-items: flex-end; gap: 10px; translate: -50% 0; }
.title-doll .doll-inner { animation: sway 2.4s ease-in-out infinite; }
.title-doll.d1 .doll-inner { animation: hop .7s ease-in-out infinite alternate; }
.title-doll.d2 .doll-inner { animation-delay: -1.2s; }

/* feedback animations */
.bump { animation: pop .3s; }
.shake { animation: shake .4s; }
.wiggle .doll-inner, .wiggle.sprite, .bowl.wiggle { animation: wiggle .45s; }
.pop-in .doll-inner { animation: pop .35s; }
.wave .doll-inner { animation: sway 2.4s ease-in-out infinite; }
.pop-in.sprite { animation: pop .35s; }
@keyframes pop { 0% { scale: .6; } 60% { scale: 1.12; } 100% { scale: 1; } }
@keyframes shake { 20%, 60% { translate: -10px 0; } 40%, 80% { translate: 10px 0; } }
@keyframes wiggle { 25% { transform: rotate(-4deg) scale(1.03); } 75% { transform: rotate(4deg) scale(1.03); } }
.btn-action.shake { animation: shake .4s; }
.confetti { position: absolute; z-index: 45; border-radius: 2px; pointer-events: none; animation: confetti 3s linear both; }
@keyframes confetti { 0% { transform: translate(0, 0) rotate(0); } 85% { opacity: 1; } 100% { transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); opacity: 0; } }
.sparkle { position: absolute; z-index: 60; font-size: 40px; pointer-events: none; text-shadow: 0 0 8px #fff; animation: sparkle 1.2s ease-out both; }
@keyframes sparkle { from { transform: translate(-50%, -50%) scale(.2); opacity: 1; } to { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.3) rotate(90deg); opacity: 0; } }
.toast { position: absolute; left: 50%; top: 130px; translate: -50% 0; z-index: 70; padding: 14px 40px 18px; border-radius: 40px; background: #fff; color: var(--pink-dark); font-size: 40px; font-weight: 800; box-shadow: 0 10px 30px rgba(0,0,0,.18); animation: toast 1.4s ease forwards; pointer-events: none; white-space: nowrap; }
@keyframes toast { 0% { opacity: 0; transform: translateY(-20px) scale(.9); } 15%, 80% { opacity: 1; transform: none; } 100% { opacity: 0; } }
