/* =============================================================================
   EXTRAS — notifications, corner heart, cursor, particles, confetti
   ========================================================================== */

/* ---------- Notifications (iOS-ish banners) -------------------------------- */
.notify-region {
  position: fixed;
  top: calc(10px + env(safe-area-inset-top));
  left: 50%;
  z-index: 90;
  display: grid;
  gap: 8px;
  width: min(390px, calc(100vw - 20px));
  transform: translateX(-50%);
  pointer-events: none;
}
@media (min-width: 768px) {
  .notify-region { top: 74px; left: auto; right: 20px; transform: none; }
}

.notif {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 12px 12px 14px;
  border-radius: 24px;
  background: rgba(255, 252, 248, .86);
  -webkit-backdrop-filter: blur(22px) saturate(1.7);
  backdrop-filter: blur(22px) saturate(1.7);
  box-shadow: 0 22px 44px -18px rgba(73, 52, 61, .5), 0 0 0 1px var(--line), inset 0 1px 0 rgba(255, 255, 255, .8);
  pointer-events: auto;
  touch-action: pan-x;
  animation: notif-in .65s var(--ease-spring) both;
}
.notif.is-out { animation: notif-out .38s ease-in forwards; }
@keyframes notif-in {
  from { opacity: 0; transform: translateY(-130%) scale(.94); }
  to { opacity: 1; transform: none; }
}
@keyframes notif-out {
  to { opacity: 0; transform: translateY(-110%) scale(.96); }
}
.notif-ic {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 11px;
  background: linear-gradient(145deg, var(--rose), var(--cherry));
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35);
}
.notif-ic .icon { width: 20px; height: 20px; }
.notif-main { flex: 1; min-width: 0; }
.notif-head { display: flex; justify-content: space-between; gap: 8px; }
.notif-app { font-size: .66rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.notif-time { font-size: .74rem; color: var(--ink-3); }
.notif-title { font-size: .92rem; font-weight: 700; line-height: 1.3; }
.notif-body { font-size: .92rem; line-height: 1.38; color: var(--ink); }
.notif-close {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  margin: -2px -2px 0 0;
  border: 0;
  border-radius: 50%;
  background: rgba(73, 52, 61, .06);
  color: var(--ink-2);
  cursor: pointer;
}
.notif-close .icon { width: 14px; height: 14px; }
.notif-close:hover { background: rgba(73, 52, 61, .12); }

.typing {
  display: inline-flex;
  gap: 4px;
  margin-top: 4px;
  padding: 9px 12px;
  border-radius: 14px;
  background: var(--blush);
}
.typing i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-3);
  animation: typing 1s ease-in-out infinite;
}
.typing i:nth-child(2) { animation-delay: .15s; }
.typing i:nth-child(3) { animation-delay: .3s; }
@keyframes typing {
  0%, 60%, 100% { transform: none; opacity: .5; }
  30% { transform: translateY(-4px); opacity: 1; }
}

/* ---------- Corner heart ---------------------------------------------------- */
.corner-heart {
  position: fixed;
  right: calc(16px + env(safe-area-inset-right));
  bottom: calc(16px + env(safe-area-inset-bottom));
  z-index: 60;
  animation: rise-in .8s var(--ease-spring) 1.6s both;
}
.corner-heart-btn {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 0;
  border-radius: 50%;
  background: var(--paper);
  color: var(--cherry);
  box-shadow: var(--shadow-md), inset 0 0 0 1px var(--line);
  cursor: pointer;
  transition: transform .35s var(--ease-spring);
}
.corner-heart-btn .icon { width: 24px; height: 24px; animation: heartbeat 3s ease-in-out infinite; }
@media (hover: hover) { .corner-heart-btn:hover { transform: scale(1.1) rotate(-8deg); } }
.corner-heart-btn.is-pop { animation: pop .5s var(--ease-spring); }

.corner-bubble {
  position: absolute;
  right: 4px;
  bottom: calc(100% + 12px);
  width: max-content;
  max-width: min(250px, calc(100vw - 40px));
  padding: 10px 14px;
  border-radius: 18px 18px 4px 18px;
  background: var(--plum);
  color: var(--cream);
  font-size: .9rem;
  line-height: 1.35;
  box-shadow: var(--shadow-md);
  transform-origin: bottom right;
  opacity: 0;
  transform: scale(.6) translateY(10px);
  visibility: hidden;
  transition: opacity .25s, transform .4s var(--ease-spring), visibility 0s .4s;
}
.corner-bubble.is-shown {
  opacity: 1;
  transform: none;
  visibility: visible;
  transition: opacity .25s, transform .4s var(--ease-spring), visibility 0s;
}

/* ---------- Cursor follower (desktop only) ---------------------------------- */
.cursor-heart {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 200;
  width: 16px;
  height: 16px;
  color: var(--rose);
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s;
  will-change: transform;
}
.cursor-heart.is-active { opacity: .85; }
.cursor-heart .icon { width: 100%; height: 100%; transition: transform .3s var(--ease-spring), color .2s; }
.cursor-heart.is-hover .icon { transform: scale(1.5); color: var(--cherry); }

/* ---------- Particles -------------------------------------------------------- */
.burst-heart {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 210;
  width: var(--s);
  height: var(--s);
  color: var(--c);
  pointer-events: none;
  animation: burst var(--dur) var(--ease-out) forwards;
}
.burst-heart svg { width: 100%; height: 100%; fill: currentColor; }
@keyframes burst {
  0% { opacity: 1; transform: translate(var(--x0), var(--y0)) scale(.3) rotate(0); }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--x1), var(--y1)) scale(1) rotate(var(--r)); }
}

.confetti-canvas {
  position: fixed;
  inset: 0;
  z-index: 220;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
