/* Assist Lifestyle motion layer — "pinned up, not pushed in".
   Paper things arrive the way they would on a fridge door: a short drop, a settle into their tilt,
   then stillness. One authored moment per page (see motion.js), quick feedback everywhere else.
   Content is visible by default: nothing is hidden unless motion.js has run and the element is
   still below the fold. Uses the individual `translate` / `rotate` / `scale` properties so every
   component keeps its own `transform` tilt untouched. */

:root {
  --m-settle: cubic-bezier(0.16, 1, 0.3, 1);
  --m-press: cubic-bezier(0.22, 1, 0.36, 1);
  --m-arrive: 620ms;
}

/* ---------- Page to page: the header stays put, the page underneath cross-fades ---------- */
@view-transition { navigation: auto; }
.site-header { view-transition-name: site-header; }
::view-transition-old(root) { animation: m-page-out 180ms ease-in both; }
::view-transition-new(root) { animation: m-page-in 320ms var(--m-settle) both; }
@keyframes m-page-out { to { opacity: 0; } }
@keyframes m-page-in { from { opacity: 0; translate: 0 10px; } }

@media (prefers-reduced-motion: no-preference) {

  /* ---------- Arrivals: pinned up as they scroll into view ---------- */
  /* Waiting to arrive: take the start pose instantly (never animate *towards* hidden), then wait. */
  .m-ready [data-m]:not(.m-in), .m-ready [data-m]:not(.m-in) :is(.polaroid__pin, .notice__pin, .magnet, .tape) { transition: none !important; }
  .m-ready [data-m]:not(.m-in) { opacity: 0; }
  .m-ready [data-m="settle"]:not(.m-in) { translate: 0 -18px; rotate: -1.5deg; }
  .m-ready [data-m="rise"]:not(.m-in) { translate: 0 14px; }
  .m-ready [data-m="pin"]:not(.m-in) { translate: 0 -22px; rotate: 3deg; scale: 1.02; }
  .m-ready [data-m="peel"]:not(.m-in) { rotate: 6deg; scale: 1.06; }
  [data-m].m-in {
    transition: opacity 420ms ease-out, translate var(--m-arrive) var(--m-settle), rotate var(--m-arrive) var(--m-settle), scale var(--m-arrive) var(--m-settle);
    transition-delay: var(--m-delay, 0ms);
  }

  /* Pins, magnets and tape land a beat after their paper. */
  .m-ready [data-m]:not(.m-in) :is(.polaroid__pin, .notice__pin, .magnet, .tape) { scale: 0; }
  [data-m].m-in :is(.polaroid__pin, .notice__pin, .magnet, .tape) { transition: scale 380ms var(--m-press) calc(var(--m-delay, 0ms) + 260ms); }

  /* Handwriting: captions and greetings write themselves on, left to right. */
  .m-ready [data-m-write]:not(.m-in) { clip-path: inset(-0.2em 100% -0.3em 0); }
  [data-m-write].m-in { clip-path: inset(-0.2em 0 -0.3em 0); transition: clip-path 1300ms cubic-bezier(0.3, 0.1, 0.3, 1) var(--m-delay, 150ms); }

  /* Stamps and postmarks press down once. */
  .m-ready [data-m-stamp]:not(.m-in) { opacity: 0; scale: 1.35; }
  [data-m-stamp].m-in { opacity: 1; scale: 1; transition: opacity 120ms linear var(--m-delay, 200ms), scale 420ms var(--m-press) var(--m-delay, 200ms); }

  /* ---------- Feedback: paper you can pick up ---------- */
  .notice { transition: transform 300ms var(--m-settle), box-shadow 300ms var(--m-settle); }
  .notice:hover, .notice:focus-within { transform: rotate(0deg) translateY(-1px); box-shadow: var(--shadow-lift); }
  .notice:hover .notice__pin { scale: 1.12; transition: scale 200ms var(--m-press); }
  .tear a { transition: translate 200ms var(--m-settle), background-color 200ms; }
  .tear a:hover { translate: 0 3px; }
  .sticky { transition: transform 300ms var(--m-settle), box-shadow 300ms var(--m-settle); }
  .sticky:hover { box-shadow: var(--shadow-lift); }
  .stamp { transition: rotate 300ms var(--m-press); }
  :is(.postcard, .pad, .letter, .index-card):hover > .stamp { rotate: -4deg; }
  .btn:active { scale: .98; }
  .btn .icon { transition: translate 250ms var(--m-settle); }
  .btn:hover .icon { translate: 3px 0; }

  /* Menus drop like a note pulled from under a magnet. */
  .mega:not([hidden]) { animation: m-drop 260ms var(--m-settle) both; }
  @keyframes m-drop { from { opacity: 0; translate: 0 -8px; } }

  /* Disclosures: the answer slides out of its card. */
  details[open] > :not(summary) { animation: m-open 280ms var(--m-settle) both; }
  @keyframes m-open { from { opacity: 0; translate: 0 -6px; } }

  /* "Sent" notes land on the pad. */
  .sent:not([hidden]) { animation: m-sent 520ms var(--m-settle) both; }
  @keyframes m-sent { from { opacity: 0; translate: 0 -20px; rotate: -3deg; } }

  /* Inline errors nudge into place instead of popping. */
  .err:not(.is-reserved) { animation: m-err 240ms var(--m-settle); }
  @keyframes m-err { from { opacity: 0; translate: 0 -4px; } }

  /* Filters and search: cards that stay re-settle; nothing slides across the page. */
  .m-refresh { animation: m-refresh 360ms var(--m-settle) both; animation-delay: var(--m-delay, 0ms); }
  @keyframes m-refresh { from { opacity: 0; scale: .97; } }

  /* ---------- Signature moments ---------- */

  /* Coco: the ID card swings on its lanyard, once, then hangs still. */
  /* Starts and ends at rest, so there is never a jump before or after the swing. */
  .lanyard[data-m-swing].m-in .id-card { animation: m-swing 1700ms cubic-bezier(0.37, 0, 0.3, 1) 150ms backwards; }
  @keyframes m-swing {
    0% { rotate: 0deg; } 18% { rotate: 7deg; } 42% { rotate: -4deg; } 64% { rotate: 2deg; } 84% { rotate: -.6deg; } 100% { rotate: 0deg; }
  }
  .lanyard[data-m-swing].m-in .dog-tag { animation: m-tag-sway 1500ms cubic-bezier(0.37, 0, 0.3, 1) 420ms backwards; }
  @keyframes m-tag-sway { 0% { rotate: 0deg; } 25% { rotate: -10deg; } 55% { rotate: 5deg; } 80% { rotate: -2deg; } 100% { rotate: 0deg; } }

  /* Rosettes: a little twist as each award is pinned on. Only while still waiting to arrive. */
  .m-ready .rosette-row li[data-m]:not(.m-in) .rosette { rotate: -25deg; scale: .6; }
  .rosette-row li.m-in .rosette { transition: rotate 700ms var(--m-press) var(--m-delay, 0ms), scale 700ms var(--m-press) var(--m-delay, 0ms); }

  /* Partners: business cards slot into the rail; the rail rests while it is off screen. */
  .cards-rail.is-offscreen .cards-rail__list { animation-play-state: paused; }
  .cards-rail .biz-card { transition: translate 260ms var(--m-settle); }
  .cards-rail .biz-card:hover { translate: 0 -1px; }

  /* Referral folder: the next section slides in from the side it's coming from. */
  .folder__step.m-step-fwd { animation: m-step-fwd 380ms var(--m-settle) both; }
  .folder__step.m-step-back { animation: m-step-back 380ms var(--m-settle) both; }
  @keyframes m-step-fwd { from { opacity: 0; translate: 32px 0; } }
  @keyframes m-step-back { from { opacity: 0; translate: -32px 0; } }
  .folder__tab { transition: background-color 200ms, translate 250ms var(--m-settle); }
  .folder__tab.is-done .folder__n { animation: m-tick 360ms var(--m-press); }
  @keyframes m-tick { from { scale: .5; } }

  /* Complaints: the slip is posted into the box. */
  .slip.m-posting { animation: m-post 640ms cubic-bezier(0.55, 0, 0.75, 0.2) forwards; transform-origin: 50% 0; }
  @keyframes m-post { 30% { translate: 0 8px; } 100% { translate: 0 -120px; scale: .7 .2; opacity: 0; } }
  .slip-wrap .box-slot.m-gulp { animation: m-gulp 420ms var(--m-press) 420ms; }
  @keyframes m-gulp { 50% { scale: 1.03 1.12; } }

  /* Contact: the postcard gets its postmark before it's sent. */
  .postcard-big .postmark.m-press { animation: m-postmark 520ms var(--m-press); }
  @keyframes m-postmark { from { scale: 1.6; opacity: 0; } }
}

/* Reduced motion: no page transitions, and motion.js tags nothing, so everything is simply there. */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* Print: everything shows, nothing waits. */
@media print {
  [data-m], [data-m-write], [data-m-stamp] { opacity: 1 !important; translate: none !important; rotate: none !important; scale: none !important; clip-path: none !important; }
}

/* ---------- Page opening: the page's main picture or paper gets stuck on ----------
   Pure CSS, so it runs on first paint with nothing hidden beforehand. `backwards` fill means
   the element only borrows the start pose during its delay and hands back its own styles after.
   The whole sequence on any page finishes within about 1.5 seconds. */
@media (prefers-reduced-motion: no-preference) {
  :is(.service-postcard, .inside-postcard, .letter, .letter-photo, .postback-hero, .album-photo--cover,
      .polaroid--big, .book-hero__photo, .front-page, .postcard-big, .clipped, .faq-find, .wall-search,
      .apply__pad .pad, .slip-wrap, .homes-hero__photo, .sil-hero__photo, .ilo-def) {
    animation: m-stick 560ms var(--m-settle) 40ms backwards;
  }
  .letter-photo, .book-hero__photo { animation-delay: 160ms; }

  /* Tape, pins and magnets press on just after; stamps and postmarks thump down last. */
  :is(.service-postcard, .inside-postcard, .letter-photo, .postback-hero, .album-photo--cover, .polaroid--big,
      .book-hero__photo, .clipped, .faq-find, .wall-search, .letter-ps, .homes-hero__photo, .sil-hero__photo, .ilo-def) :is(.tape, .polaroid__pin, .magnet, .clipped__clip) {
    animation: m-tape 320ms var(--m-press) 340ms backwards;
  }
  :is(.album-photo--cover, .book-hero__photo) .corners { animation: m-corners 360ms ease-out 340ms backwards; }
  :is(.service-postcard, .inside-postcard, .postback-hero, .letter, .postcard-big, .apply__pad, .album-photo--cover, .sil-hero__photo) :is(.stamp, .postmark-ring, .postmark) {
    animation: m-thump 360ms var(--m-press) 480ms backwards;
  }
  .postback-hero .postmark-ring { animation-delay: 560ms; }

  /* Handwriting on the opening picture writes itself in after it lands. */
  :is(.service-postcard, .inside-postcard, .letter-photo, .album-photo--cover, .book-hero__photo, .homes-hero__photo, .sil-hero__photo) figcaption,
  .letter .letter__dear, .postcard-big__address h2, .apply__pad .pad__to {
    animation: m-write 1100ms cubic-bezier(0.3, 0.1, 0.3, 1) 400ms backwards;
  }
  /* Suburb postcards: the address lines are written one after another. */
  .postback-hero .addr-line { animation: m-write 800ms cubic-bezier(0.3, 0.1, 0.3, 1) 300ms backwards; }
  .postback-hero .addr-line:nth-of-type(2) { animation-delay: 480ms; }
  .postback-hero .addr-line:nth-of-type(3) { animation-delay: 660ms; }

  /* Staff profile: the name badge is peeled off its backing and pressed on. */
  .name-badge { animation: m-peel 520ms var(--m-press) 200ms backwards; }

  /* Careers: the four notices are pinned up one by one. */
  .notices .notice { animation: m-stick 520ms var(--m-settle) backwards; }
  .notices .notice:nth-child(1) { animation-delay: 60ms; }
  .notices .notice:nth-child(2) { animation-delay: 150ms; }
  .notices .notice:nth-child(3) { animation-delay: 240ms; }
  .notices .notice:nth-child(4) { animation-delay: 330ms; }
  .notices .notice .notice__pin { animation: m-tape 320ms var(--m-press) backwards; }
  .notices .notice:nth-child(1) .notice__pin { animation-delay: 300ms; }
  .notices .notice:nth-child(2) .notice__pin { animation-delay: 390ms; }
  .notices .notice:nth-child(3) .notice__pin { animation-delay: 480ms; }
  .notices .notice:nth-child(4) .notice__pin { animation-delay: 570ms; }

  /* Overview pages: the first row of postcards goes up on the fridge door. */
  .topic-cards > .topic-card:nth-child(-n+4) { animation: m-stick 520ms var(--m-settle) backwards; }
  .topic-cards > .topic-card:nth-child(1) { animation-delay: 40ms; }
  .topic-cards > .topic-card:nth-child(2) { animation-delay: 110ms; }
  .topic-cards > .topic-card:nth-child(3) { animation-delay: 180ms; }
  .topic-cards > .topic-card:nth-child(4) { animation-delay: 250ms; }

  /* Team wall: the first row of faces is pinned up one by one. */
  .wall-hero + .wall-group .polaroid:nth-child(-n+5) { animation: m-stick 520ms var(--m-settle) backwards; }
  .wall-hero + .wall-group .polaroid:nth-child(1) { animation-delay: 100ms; }
  .wall-hero + .wall-group .polaroid:nth-child(2) { animation-delay: 180ms; }
  .wall-hero + .wall-group .polaroid:nth-child(3) { animation-delay: 260ms; }
  .wall-hero + .wall-group .polaroid:nth-child(4) { animation-delay: 340ms; }
  .wall-hero + .wall-group .polaroid:nth-child(5) { animation-delay: 420ms; }
  .wall-hero + .wall-group .polaroid:nth-child(-n+5) .polaroid__pin { animation: m-tape 320ms var(--m-press) 620ms backwards; }

  /* Feedback box: the slot opens a moment before the slip slides up to it. */
  .slip-wrap .box-slot { animation: m-slot 400ms var(--m-settle) backwards; }

  @keyframes m-stick {
    0% { opacity: 0; translate: 0 -20px; scale: var(--m-stick-scale, 1.045); rotate: var(--m-stick-rotate, -2.5deg); }
    55% { opacity: 1; }
    72% { translate: 0 2px; scale: .996; rotate: .3deg; }
  }
  @keyframes m-tape { from { opacity: 0; scale: 1.6; rotate: -8deg; } }
  @keyframes m-corners { from { opacity: 0; } }
  @keyframes m-thump { 0% { opacity: 0; scale: 1.5; } 60% { opacity: 1; scale: .94; } }
  /* A soft-edged pen stroke: a feathered mask slides across at an even writing pace.
     The mask only exists while the animation runs, so it can never clip a descender afterwards. */
  @keyframes m-write {
    from { -webkit-mask: linear-gradient(90deg, #000 40%, transparent 60%) 100% 0 / 260% 100% no-repeat; mask: linear-gradient(90deg, #000 40%, transparent 60%) 100% 0 / 260% 100% no-repeat; }
    to { -webkit-mask: linear-gradient(90deg, #000 40%, transparent 60%) 0 0 / 260% 100% no-repeat; mask: linear-gradient(90deg, #000 40%, transparent 60%) 0 0 / 260% 100% no-repeat; }
  }
  @keyframes m-peel { 0% { opacity: 0; rotate: 8deg; scale: 1.08; translate: 12px -10px; } 60% { opacity: 1; scale: .98; } }
  @keyframes m-slot { from { opacity: 0; scale: .9 .6; } }

  /* Phones: smaller start poses, so full-width paper never pokes past the screen edge. */
  @media (max-width: 40rem) {
    :root { --m-stick-scale: 1.01; --m-stick-rotate: -1deg; }
    .m-ready [data-m="pin"]:not(.m-in) { rotate: 1deg; scale: 1; }
  }
}
