/* ============================================================
   PAWZI OS — motion
   ============================================================ */

/* ---------- window open / minimise ------------------------
   Hidden states are gated on .js (set by an inline head script) so a
   scripting failure leaves the page fully readable rather than blank. */
.js .win[data-win] {
  opacity: 0;
  transform: translateY(26px) scale(.975);
  transform-origin: 50% 100%;
  transition: opacity .5s var(--ease-win), transform .5s var(--ease-win);
}
.js .win[data-win].is-open { opacity: 1; transform: none; }

.win[data-win].is-min {
  opacity: 0;
  transform: translateY(60px) scaleY(.02) scaleX(.5);
  pointer-events: none;
  height: 0; margin: 0; padding: 0; overflow: hidden;
  transition: opacity .28s ease, transform .3s var(--ease-win), height .3s var(--ease-win),
              margin .3s var(--ease-win), padding .3s var(--ease-win);
}
.win[data-win].is-max {
  position: fixed; inset: 28px 0 var(--taskbar-h); z-index: 200;
  overflow: auto; margin: 0; max-width: none;
}

/* wireframe "opening" ghost, like Win98 zoom rects */
.zoomrect {
  position: fixed; z-index: 400; pointer-events: none;
  border: 2px dotted #fff;
  mix-blend-mode: difference;
  animation: zoomRect .32s linear forwards;
}

/* ---------- reveal ---------------------------------------- */
.js [data-rise] { opacity: 0; transform: translateY(16px); transition: opacity .55s var(--ease-win), transform .55s var(--ease-win); }
.js [data-rise].is-in { opacity: 1; transform: none; }

/* ---------- keyframes ------------------------------------- */
@keyframes driftNear    { to { transform: translate3d(-900px, 0, 0); } }
@keyframes driftFar     { to { transform: translate3d(1350px, 0, 0); } }
@keyframes driftHero    { to { transform: translate3d(-640px, 0, 0); } }
@keyframes driftPaws    { to { transform: translate3d(-384px, 384px, 0); } }
@keyframes pawFade      { 0% { opacity: 0; transform: scale(.55); }
                          14% { opacity: .85; transform: scale(1); }
                          100% { opacity: 0; transform: scale(1); } }
@keyframes pawFloat     { 0%,100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-22px) rotate(2deg); } }
@keyframes pawPulse     { 0%,100% { transform: scale(1); filter: drop-shadow(0 0 0 rgba(120,180,255,0)); }
                          50%     { transform: scale(1.07); filter: drop-shadow(0 0 14px rgba(120,180,255,.6)); } }
@keyframes barSweep     { 0% { transform: translateX(-130%); } 22%,100% { transform: translateX(230%); } }
@keyframes marqueeRun   { to { transform: translate3d(-50%, 0, 0); } }
@keyframes crtRoll      { 0% { transform: translateY(-120%); } 100% { transform: translateY(320%); } }
@keyframes crtOff       { 0% { transform: scaleY(1); opacity: 1; } 45% { transform: scaleY(.006); opacity: 1; }
                          55% { transform: scaleY(.006); } 100% { transform: scaleY(1); opacity: 1; } }
@keyframes menuUp       { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes toastIn      { from { transform: translateX(24px) scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes bootLine     { to { opacity: 1; } }
@keyframes zoomRect     { from { opacity: 1; } to { opacity: 0; } }
@keyframes feedIn       { from { opacity: 0; transform: translateX(-14px); } to { opacity: 1; transform: none; } }
@keyframes qIn          { from { opacity: 0; transform: translateX(-26px) scale(.9); } to { opacity: 1; transform: none; } }
@keyframes qPaid        { 0% { transform: none; } 60% { transform: translateY(-14px) scale(1.06); }
                          100% { transform: translateY(-56px) scale(.7); opacity: 0; } }
@keyframes stampIn      { 0% { transform: rotate(-40deg) scale(2.6); opacity: 0; }
                          70% { transform: rotate(-11deg) scale(.92); opacity: 1; }
                          100% { transform: rotate(-14deg) scale(1); opacity: 1; } }
@keyframes petRise      { from { transform: translateY(104%); } to { transform: translateY(0); } }
@keyframes petBob       { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes heartUp      { 0%   { transform: translate(0,0) scale(.6) rotate(0deg); opacity: 1; }
                          100% { transform: translate(var(--dx,0), -150px) scale(1.25) rotate(var(--rot,20deg)); opacity: 0; } }
@keyframes blink        { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }
@keyframes shake        { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-4px); }
                          40% { transform: translateX(4px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(3px); } }
@keyframes palBob       { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes glowPulse    { 0%,100% { box-shadow: 0 0 0 0 rgba(255,159,183,0); } 50% { box-shadow: 0 0 0 7px rgba(255,159,183,.28); } }

/* ---------- applied helpers ------------------------------- */
.hero__pets > img { animation: petRise 1.05s var(--ease-win) .25s both, petBob 7.5s ease-in-out 1.3s infinite; }
.hero__pets:hover > img { animation-play-state: running, paused; }

.wordmark__paw { animation: pawFloat 6s ease-in-out infinite; }

/* Companions step out from behind their window and then breathe. They start
   tucked toward the window rather than away from it, so the entrance never
   pokes past the viewport edge or into the icon dock. The entrance uses the
   standalone `translate` property and the idle uses `transform`, so the two
   compose instead of the animation stomping the transition. */
.js .pal { opacity: 0; translate: var(--from, -30px) 0;
  transition: opacity .6s var(--ease-win), translate .6s var(--ease-win); }
.js .pal--l { --from: 30px; }
.js .pal.is-in { opacity: 1; translate: none; }
.pal { animation: palBob 4.4s ease-in-out infinite; }
.pal--l { animation-duration: 5.1s; animation-delay: -1.7s; }
.caret { display: inline-block; width: .55em; height: 1.05em; background: var(--ink);
  vertical-align: -.16em; animation: blink 1.05s steps(1) infinite; }
.btn--cta { animation: glowPulse 2.8s ease-in-out infinite; }
.shake { animation: shake .4s ease; }

/* Marquee: exactly two identical copies, wrapper shifted -50%, so the loop
   is seamless and the strip is never empty on first paint. */
.marquee { overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); }
.marquee > div { display: flex; width: max-content; animation: marqueeRun 30s linear infinite; }
.marquee span { white-space: nowrap; padding-right: 48px; }
.marquee:hover > div, #topbar .ticker:hover > div { animation-play-state: paused; }

/* ---------- reduced motion -------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .js .win[data-win] { opacity: 1; transform: none; }
  .js [data-rise] { opacity: 1; transform: none; }
  .js .pal { opacity: 1; translate: none; }
  .hero__pets > img { animation: none; }
  body.crt #crt::after { display: none; }
}
