/* Home page motion layer. Everything here is decoration on top of fun.css.
   motion.js adds .motion to <html> only when the visitor has not asked for reduced motion,
   so without JS, or with reduced motion, the page shows its normal static state.
   Colours come from the site tokens only. Animations use transform and opacity. */

/* Reading progress and header state (driven by the visitor's own scrolling). */
.scroll-progress { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 100; pointer-events: none; }
.scroll-progress span { display: block; height: 100%; background: var(--accent); transform-origin: 0 50%; transform: scaleX(0); }
header.site.sticky { transition: box-shadow .3s ease; }
header.site.sticky.scrolled { box-shadow: 0 6px 24px rgba(20, 30, 60, .10); }
nav.site a { position: relative; }
nav.site a::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; border-radius: 2px; background: var(--accent); transform: scaleX(0); transform-origin: 0 50%; transition: transform .25s cubic-bezier(.2, .8, .2, 1); }
@media (hover: hover) and (pointer: fine) { nav.site a:hover::after { transform: scaleX(1); } }

/* ---------- Hero ---------- */
/* Floating files: ZIP boxes that flip over into the files inside them. */
.floaties { position: absolute; inset: 0; pointer-events: none; }
button.floaty { pointer-events: auto; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; z-index: 2; }
button.floaty:focus { outline: none; }
button.floaty:focus-visible .floaty-card i { box-shadow: 0 0 0 3px var(--accent), var(--shadow); }
button.floaty:hover .floaty-card { scale: 1.08; }
.floaty-card i.floaty-mascot { padding: 17%; overflow: hidden; }
.floaty-card i.floaty-mascot svg { width: 100%; height: 100%; }
.floaty.pink .floaty-card i + i { border-color: #ff5c93; background: color-mix(in srgb, #ff5c93 22%, transparent); box-shadow: 0 0 0 4px color-mix(in srgb, #ff5c93 30%, transparent), 0 0 40px #ff5c93; }
.pink-prize { position: fixed; z-index: 50; left: 50%; bottom: 20px; translate: -50% 0; width: min(100% - 32px, 460px); display: grid; gap: 8px; padding: 16px 44px 16px 18px;
  border-radius: 16px; background: var(--card); color: var(--ink); border: 2px solid #ff5c93; box-shadow: 0 20px 50px rgba(0,0,0,.35); animation: pink-in .5s cubic-bezier(.3, 1.5, .5, 1); }
.pink-prize span { color: var(--muted); font-size: 14px; }
.pink-prize code { color: var(--ink); font-weight: 700; }
.pink-prize .pink-share { margin: 0; color: var(--ink); font-size: 14px; }
.pink-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.pink-close { position: absolute; top: 8px; right: 10px; border: 0; background: none; color: var(--muted); font-size: 22px; line-height: 1; cursor: pointer; }
@keyframes pink-in { from { opacity: 0; transform: translateY(30px) scale(.9); } }
.floaty-bob, .floaty-pop, .floaty-card { display: block; }
.floaty { position: absolute; width: var(--s); height: var(--s); margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  transform: translate3d(calc(var(--px, 0) * var(--depth) * 1px), calc(var(--py, 0) * var(--depth) * 1px), 0); transition: transform .5s cubic-bezier(.2, .8, .2, 1); }
.floaty-bob { width: 100%; height: 100%; animation: floaty-bob var(--t, 5s) ease-in-out infinite alternate; animation-delay: calc(var(--i) * -.9s); }
.floaty-pop { width: 100%; height: 100%; perspective: 500px; transform: rotate(var(--rot)); animation: floaty-in .7s cubic-bezier(.3, 1.5, .5, 1) backwards; animation-delay: calc(.9s + var(--i) * .1s); }
.floaty-card { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; transition: transform .8s cubic-bezier(.3, 1.4, .4, 1); }
.floaty.flipped .floaty-card { transform: rotateY(180deg); }
.floaty-card i { position: absolute; inset: 0; display: grid; place-items: center; font-style: normal; font-size: calc(var(--s) * .5); line-height: 1;
  background: var(--card); border: 1px solid var(--line); border-radius: 24%; box-shadow: var(--shadow); backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.floaty-card i + i { transform: rotateY(180deg); border-color: var(--accent); background: var(--accent-soft); }
@keyframes floaty-bob { from { transform: translateY(-9px) rotate(-2deg); } to { transform: translateY(9px) rotate(2deg); } }
@keyframes floaty-in { from { opacity: 0; transform: rotate(var(--rot)) scale(.2) translateY(40px); } }
@media (max-width: 1000px) { .floaty { opacity: .55; --s: 46px !important; } .floaty:nth-child(2), .floaty:nth-child(5) { display: none; } }
@media (max-width: 640px) { .floaty { opacity: .4; } .floaty:nth-child(3), .floaty:nth-child(6) { display: none; } .floaty:nth-child(1) { top: 7% !important; } .floaty:nth-child(4) { top: 6% !important; } }

/* The title's accent word does one full flip after it lands. */
.motion .flip-title .word.accent { animation: flip-in .8s cubic-bezier(.2, .9, .3, 1.25) both, word-flip 1s cubic-bezier(.3, 1.3, .4, 1) 2s; animation-delay: calc(var(--i) * .22s), 2s; }
@keyframes word-flip { from { transform: rotateX(0); } to { transform: rotateX(360deg); } }
/* The rest of the hero follows the title in, one line after another. */
.motion .fun-hero .eyebrow { animation: hero-pop .6s cubic-bezier(.3, 1.5, .5, 1) backwards; }
.motion .fun-hero .lede { animation: hero-rise .8s cubic-bezier(.2, .8, .2, 1) .75s backwards; }
.motion .fun-hero .actions { animation: hero-rise .8s cubic-bezier(.2, .8, .2, 1) .95s backwards; }
.motion .fun-hero .fineprint { animation: hero-rise .8s cubic-bezier(.2, .8, .2, 1) 1.1s backwards; }
.motion .fun-hero .drive-badge { animation: hero-pop .6s cubic-bezier(.3, 1.5, .5, 1) 1.3s backwards; }
@keyframes hero-rise { from { opacity: 0; transform: translateY(26px); } }
@keyframes hero-pop { from { opacity: 0; transform: scale(.6); } }

/* Buttons: a light sweeps across primary buttons; the hero buttons lean toward the pointer. */
.motion .button.primary:not(.is-disabled) { position: relative; overflow: hidden; }
.motion .button.primary:not(.is-disabled)::after { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 45%; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent); transform: translateX(-130%) skewX(-18deg); animation: shine 4.5s ease-in-out 2s infinite; }
@keyframes shine { 0%, 62% { transform: translateX(-130%) skewX(-18deg); } 100% { transform: translateX(340%) skewX(-18deg); } }
.motion .fun-hero .button.magnet { transition: transform .25s cubic-bezier(.2, .8, .2, 1), box-shadow .15s, background .15s; }
.motion .fun-hero .button.magnet, .motion .fun-hero .button.magnet:hover { transform: translate(var(--bx, 0px), var(--by, 0px)); }
.motion .fun-hero .button.magnet:active { transform: translate(var(--bx, 0px), var(--by, 0px)) scale(.96); }

/* The blobs drift up as the page scrolls. */
@supports (animation-timeline: view()) {
  .motion .blobs { animation: blobs-away linear both; animation-timeline: scroll(root); animation-range: 0 700px; }
}
@keyframes blobs-away { to { transform: translateY(-140px); } }
/* Scrolling away from the hero pushes it back: the text sinks and fades, the floating files spread out (--hs runs 0 to 1, set by motion.js). */
.motion .fun-hero > .wrap { transform: translateY(calc(var(--hs, 0) * 80px)) scale(calc(1 - var(--hs, 0) * .1)); opacity: calc(1 - var(--hs, 0) * 1.2); }
.motion .floaties { transform: scale(calc(1 + var(--hs, 0) * .45)); opacity: calc(1 - var(--hs, 0) * .9); }

/* ---------- Section headings: words rise in one by one ---------- */
.motion .section-title.split { opacity: 1; transform: none; }
.section-title .words { display: block; }
.motion .section-title.split .w { display: inline-block; opacity: 0; transform: translateY(.7em) rotate(5deg); transition: opacity .5s ease, transform .7s cubic-bezier(.3, 1.4, .4, 1); transition-delay: calc(var(--w) * 55ms); }
.motion .section-title.split.shown .w { opacity: 1; transform: none; }

/* ---------- Groups that enter in a stagger when scrolled to (.in is added by motion.js) ---------- */
.motion .pains:not(.in) .pain, .motion .compare:not(.in) li, .motion .trust:not(.in) li { opacity: 0; }
.motion .pains.in .pain { animation: pop-in .55s cubic-bezier(.3, 1.5, .5, 1) backwards; animation-delay: calc(var(--n) * 65ms); }
@keyframes pop-in { from { opacity: 0; transform: translateY(26px) scale(.8) rotate(-3deg); } }

/* Safety cards tip up into place, then each one peeks at its back. */
.motion .flips { perspective: 1200px; }
.motion .flips .flip-card.reveal { transform: translateY(46px) rotateX(-42deg) scale(.9); transition-delay: calc(var(--n) * 80ms); }
.motion .flips .flip-card.reveal.shown { transform: none; }
.flip-card.peek .front { transform: rotateY(-180deg); }
.flip-card.peek .back { transform: rotateY(0); }

/* Before and after: the mess tumbles in, the tidy folders slide in. */
.motion .compare.in .mess li { animation: mess-drop .6s cubic-bezier(.3, 1.4, .5, 1) backwards; animation-delay: calc(var(--n) * 45ms); }
.motion .compare.in .tidy li { animation: tidy-in .6s cubic-bezier(.2, .8, .2, 1) backwards; animation-delay: calc(.2s + var(--n) * 90ms); }
@keyframes mess-drop { from { opacity: 0; transform: translateY(-46px) rotate(-22deg) scale(.6); } }
@keyframes tidy-in { from { opacity: 0; transform: translateX(36px); } }
.motion .compare .handle span { animation: handle-nudge 2.4s ease-in-out infinite; }
@keyframes handle-nudge { 0%, 100% { transform: translate(-50%, -50%) scale(1); } 50% { transform: translate(-50%, -50%) scale(1.14); } }

/* Calculator number and step badges pop. */
.motion .calc.shown .big-number { animation: number-pop .8s cubic-bezier(.3, 1.6, .5, 1) .25s backwards; }
@keyframes number-pop { from { opacity: 0; transform: scale(.4) rotate(-6deg); } }
.motion .step-card.shown { animation: step-in .8s cubic-bezier(.3, 1.3, .4, 1) var(--d, 0s) backwards; }
.motion .step-card.shown::before { animation: badge-pop .7s cubic-bezier(.3, 1.8, .5, 1) calc(var(--d, 0s) + .45s) backwards; }
@keyframes step-in { from { opacity: 0; transform: translateY(46px) rotate(-3deg) scale(.92); } }
@keyframes badge-pop { from { transform: scale(0) rotate(-90deg); } }

/* Drive and Dropbox logos swing in. */
.motion .drive-card.shown .brand-tile { animation: tile-in .9s cubic-bezier(.3, 1.6, .5, 1) .2s backwards; }
@keyframes tile-in { from { opacity: 0; transform: scale(.3) rotate(-40deg); } }

/* ---------- Cards lean toward the pointer, with a soft accent glow under it ---------- */
.tilt { position: relative; }
.price-card.tilt { transition: transform .35s cubic-bezier(.2, .8, .2, 1); }
.tilt::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity .3s ease;
  background: radial-gradient(260px circle at var(--gx, 50%) var(--gy, 50%), color-mix(in srgb, var(--accent) 16%, transparent), transparent 70%); }
.tilt.tilting::after { opacity: 1; }
.js .tilt.tilting, .js .card.lift.tilt.tilting, .js .reveal.shown.tilt.tilting { transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-4px); transition: transform .12s ease-out; }

/* ---------- Pricing ---------- */
.motion .plans:not(.in) .price-card { opacity: 0; }
.motion .plans.in .price-card { animation: step-in .8s cubic-bezier(.3, 1.3, .4, 1) var(--d, 0s) backwards; }
.motion .plans.in .price-card li { animation: tidy-in .5s cubic-bezier(.2, .8, .2, 1) backwards; animation-delay: calc(var(--d, 0s) + .35s + var(--n) * 60ms); }
.motion .plans.in .price-card .amount { animation: number-pop .8s cubic-bezier(.3, 1.6, .5, 1) calc(var(--d, 0s) + .3s) backwards; }
/* Unlimited: the accent border keeps turning. */
@property --ring { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.motion .price-card-paid { border-color: transparent;
  background: linear-gradient(var(--card), var(--card)) padding-box, conic-gradient(from var(--ring), var(--accent-text), var(--accent-soft) 30%, var(--accent-text) 55%, var(--accent-soft) 80%, var(--accent-text)) border-box; }
.motion .plans.in .price-card-paid { animation: step-in .8s cubic-bezier(.3, 1.3, .4, 1) var(--d, 0s) backwards, ring 5s linear infinite; }
@keyframes ring { to { --ring: 360deg; } }
.motion .trust.in li { animation: pop-in .5s cubic-bezier(.3, 1.5, .5, 1) backwards; animation-delay: calc(var(--n) * 110ms); }

/* ---------- FAQ ---------- */
summary { transition: color .2s ease; }
@media (hover: hover) and (pointer: fine) { summary:hover { color: var(--accent-text); } }
.motion details[open] > p { animation: faq-open .4s cubic-bezier(.2, .8, .2, 1); }
@keyframes faq-open { from { opacity: 0; transform: translateY(-8px); } }

/* ---------- How it works: a line fills as the steps scroll past, and each number lights up (--sp and .lit, set by motion.js) ---------- */
.motion .steps { position: relative; padding-top: 22px; }
.motion .steps::before, .motion .steps::after { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 4px; border-radius: 4px; background: var(--line); }
.motion .steps::after { background: var(--accent); transform: scaleX(var(--sp, 0)); transform-origin: 0 50%; }
.motion .steps .card::before { transition: background .3s, color .3s, transform .35s cubic-bezier(.3, 1.5, .5, 1); }
.motion .steps .card.lit::before { background: var(--accent); color: #fff; transform: scale(1.15); }
