/* r20 motion round (client 3 Oct: "website sections are so basic, they don't even have some good animation").
   docs-motion-audit.md lists what each section had and what it got. Rules kept from the brand:
   transform / translate / scale / opacity only; scroll-linked parts are CSS view timelines (compositor), the rest
   IntersectionObserver classes from site.js (.is-in); everything sits behind html.motion (no reduced motion, not
   paused), so the static layout is the final state. Locked = amber, released = green; no glow, no borders.
   Selectors carry the section id: more.css loads later in the body and must not win over these. */

/* ============================================================ shared: the landscape photos zoom out with the scroll
   Each photo layer starts 16 % large and a little high and settles as its panel crosses the screen (the scale always
   covers the drift, so no edge ever shows; the panel clips it). */
#links .mr-art { isolation: isolate; overflow: hidden; background: #CDEFDE; }
#links .mr-art::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg, rgb(228 248 238 / .3), rgb(205 239 222 / .15)), var(--land-grass) 50% 50% / cover no-repeat, #CDEFDE;
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    html.motion #links .mr-art::before, html.motion #why.tint-land::before, html.motion #safety.tint-forest::before, html.motion #features.tint-quiet::before {
      will-change: transform; animation: land-zoom linear both; animation-timeline: view(); animation-range: cover 0% cover 100%;
    }
  }
}
@keyframes land-zoom { from { transform: scale(1.16) translate3d(0, -4%, 0); } to { transform: scale(1.06) translate3d(0, 2.5%, 0); } }

/* entrances only: a hidden state never transitions (it is applied at load; a fade-out still running when someone lands
   on the section early would make the entrance start half way). The site-wide rule keeps it for other sections. */
html.reveal-ready :is(#links, #rules, #builder, #features, #why, #safety, #compare) [data-reveal]:not(.is-in) { transition: none; }

/* ============================================================ links: the link the buyer opens
   The card drifts against the meadow (depth), the amount rolls in digit by digit (site.js splits it), the rows land,
   Fund fills and is pressed, the money locks and the lock settles. Locked stays amber. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    html.motion #links .lk { animation: lk-drift linear both; animation-timeline: view(); animation-range: cover 0% cover 100%; }
  }
}
@keyframes lk-drift { from { translate: 0 28px; } to { translate: 0 -28px; } }
.lk-ch { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .14em; margin-bottom: -.14em; }
.lk-ch > span { display: inline-block; }
html.motion .lk:not(.is-in) .lk-ch > span { transform: translate3d(0, 110%, 0); }
html.motion .lk.is-in .lk-ch > span { transition: transform .8s var(--ease) calc(var(--ci, 0) * 45ms + .15s); }
html.motion #links .lk-fund { position: relative; overflow: hidden; isolation: isolate; }
html.motion #links .lk-fund::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--brand-hover); transform-origin: 0 50%; transform: scaleX(0); }
html.motion #links .lk.is-in .lk-fund::before { animation: lk-fill 1s var(--ease) .45s both; }
html.motion #links .lk.is-in .lk-done .i { animation: lk-click .6s var(--ease) 2.05s both; }
@keyframes lk-fill { to { transform: none; } }
@keyframes lk-click { 0% { transform: translate3d(0, -3px, 0) scale(1.2); } 60% { transform: translate3d(0, 1px, 0) scale(.96); } 100% { transform: none; } }

/* ============================================================ rules: the six cards come in one after another (stagger in
   rules.html) from a little lower and smaller, and lift on hover; each card's scene plays inside it as before */
html.reveal-ready #rules .rgrid > [data-reveal]:not(.is-in) { transform: translate3d(0, 28px, 0) scale(.97); transition: none; }
html.reveal-ready #rules .rgrid > .is-in { transition: opacity .8s var(--ease) var(--d, 0s), transform .8s var(--ease) var(--d, 0s), background-color var(--t2) var(--ease); }
@media (hover: hover) and (pointer: fine) {
  html.motion #rules .rcard.is-in:hover { transform: translate3d(0, -6px, 0); background: color-mix(in srgb, var(--field) 55%, var(--ground-2)); }
}

/* ============================================================ builder: rows land in turn; a source switch re-types the rule
   (site.js adds .is-swap); the line between steps fills (transform) instead of snapping its colour; the amount waits
   amber and turns green only at Released */
html.reveal-ready #builder .rb:not(.is-in) .rb-row { opacity: 0; transform: translate3d(0, 22px, 0); }
html.reveal-ready #builder .rb.is-in .rb-row { transition: opacity .7s var(--ease), transform .7s var(--ease); }
html.reveal-ready #builder .rb.is-in .rb-row:nth-child(2) { transition-delay: .12s; }
html.reveal-ready #builder .rb.is-in .rb-row:nth-child(3) { transition-delay: .24s; }
html.motion #builder .rb-card.is-swap .rb-v { animation: rb-swap .55s var(--ease) both; }
html.motion #builder .rb-card.is-swap .rb-row:nth-child(2) .rb-v { animation-delay: .09s; }
@keyframes rb-swap { from { opacity: 0; transform: translate3d(0, 12px, 0); } to { opacity: 1; transform: none; } }
#builder .rb-flow li:not(:last-child)::after { background: var(--field); }
#builder .rb-flow li:not(:last-child)::before { content: ""; position: absolute; z-index: 1; left: 60px; right: 12px; top: 22.5px; height: 3px; border-radius: 3px; background: var(--lock); transform-origin: 0 50%; transform: scaleX(0); }
html.motion #builder .rb-flow li:not(:last-child)::before { transition: transform .9s var(--ease); }
#builder .rb-flow[data-step="2"] li:nth-child(-n+1)::before, #builder .rb-flow[data-step="3"] li:nth-child(-n+2)::before, #builder .rb-flow[data-step="4"] li::before { transform: none; }
#builder [data-rb-then] b.num { background: var(--lock-soft); color: var(--lock-text); transition: background-color .5s var(--ease), color .5s var(--ease); }
#builder .rb:has(.rb-flow[data-step="4"]) [data-rb-then] b.num { background: var(--paid-soft); color: var(--paid-text); }
html.motion #builder .rb-flow[data-step="4"] li.pine i { animation: rb-pop .6s var(--ease) both; }
@keyframes rb-pop { 0% { transform: scale(.8); } 55% { transform: scale(1.16); } 100% { transform: scale(1.08); } }
@media (max-width: 600px) { #builder .rb-flow li:not(:last-child)::before { left: 42px; right: 6px; top: 16.5px; } }

/* ============================================================ features: >= 1100 px a sticky head on the left, the nine cards
   in two columns on the right, the second column drifting against the scroll (one view timeline on the grid); every
   card's icon turns in after the card lands. Below 1100 px the centred grid stays. */
html.reveal-ready #features .ft-card:not(.is-in) i { opacity: 0; transform: scale(.55) rotate(-24deg); transition: none; }
html.reveal-ready #features .ft-card.is-in i { transition: opacity .6s var(--ease) calc(var(--d, 0s) + .22s), transform .8s var(--ease) calc(var(--d, 0s) + .22s), background-color var(--t2) var(--ease), color var(--t2) var(--ease); }
@media (hover: hover) and (pointer: fine) {
  html.motion #features .ft-card.is-in:hover i { transform: rotate(-8deg) scale(1.06); }
}
@media (min-width: 1100px) {
  #features .ft-wrap { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: clamp(40px, 5vw, 88px); align-items: start; }
  #features .ft-head { position: sticky; top: calc(var(--pill-b) + 56px); justify-items: start; text-align: left; }
  #features .ft-head .h2 { max-width: 11ch; }
  #features .ft-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: none; margin: 0; view-timeline-name: --ftg; }
}
@supports (animation-timeline: view()) {
  @media (min-width: 1100px) and (prefers-reduced-motion: no-preference) {
    html.motion #features .ft-grid > li:nth-child(even) { animation: ft-col linear both; animation-timeline: --ftg; animation-range: cover 0% cover 100%; }
  }
}
@keyframes ft-col { from { translate: 0 120px; } to { translate: 0 -40px; } }

/* ============================================================ why: the scroll brings buyer and seller in from the sides; the
   line meets in the middle, TrustPay lands on it, and only then does the seller's Delivered show */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    html.motion #why .wy { view-timeline-name: --wy; }
    html.motion #why .wy-card { animation: wy-in-l linear both; animation-timeline: --wy; animation-range: entry 0% cover 26%; }
    html.motion #why .wy-card:last-child { animation-name: wy-in-r; }
    html.motion #why .wy .wy-line { animation: wy-line linear both; animation-timeline: --wy; animation-range: cover 12% cover 28%; transition: none; }
    html.motion #why .wy .wy-mark { animation: wy-mark linear both; animation-timeline: --wy; animation-range: cover 16% cover 30%; transition: none; }
    html.motion #why .wy .wy-say { animation: wy-fade linear both; animation-timeline: --wy; animation-range: cover 22% cover 30%; transition: none; }
    html.motion #why .wy-card:last-child .chip { animation: wy-chip linear both; animation-timeline: --wy; animation-range: cover 22% cover 30%; }
  }
}
@keyframes wy-in-l { from { opacity: .35; translate: -72px 0; } to { opacity: 1; translate: 0 0; } }
@keyframes wy-in-r { from { opacity: .35; translate: 72px 0; } to { opacity: 1; translate: 0 0; } }
@keyframes wy-line { from { transform: scaleX(0); } to { transform: none; } }
@keyframes wy-mark { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: none; } }
@keyframes wy-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes wy-chip { from { opacity: 0; transform: scale(.85); } to { opacity: 1; transform: none; } }
@media (max-width: 860px) {
  @keyframes wy-in-l { from { opacity: .35; translate: -28px 0; } to { opacity: 1; translate: 0 0; } }
  @keyframes wy-in-r { from { opacity: .35; translate: 28px 0; } to { opacity: 1; translate: 0 0; } }
  @keyframes wy-line { from { transform: scaleY(0); } to { transform: none; } }
}
@media (hover: hover) and (pointer: fine) {
  html.motion #why .wy-card { transition: transform var(--t2) var(--ease); }
  html.motion #why .wy-card:hover { transform: translate3d(0, -4px, 0); }
}

/* ============================================================ safety: >= 1024 px the head on the left and the four facts as
   tiles in a 2 x 2 on the right; tiles land in turn, each icon turns in after its tile, tiles lift on hover */
@media (min-width: 1024px) {
  #safety .sf { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(40px, 5vw, 88px); align-items: center; }
  #safety .sf .sec-head.center { text-align: left; }
  #safety .sf .sec-head.center .h2, #safety .sf .sec-head.center .sub { margin-inline: 0; }
  #safety .sf .sec-head .h2 { max-width: 12ch; }
  #safety .sf .trust { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 0; padding: 0; background: none; }
  #safety .sf .trust li { grid-row: auto; display: flex; flex-direction: column; align-items: flex-start; padding: clamp(24px, 2.4vw, 34px); border-radius: 24px; background: rgb(255 255 255 / .07); }
  #safety .sf .trust-link { margin-top: auto; padding-top: 14px; }
}
html.reveal-ready #safety .trust > [data-reveal]:not(.is-in) { transform: translate3d(0, 24px, 0) scale(.97); transition: none; }
html.reveal-ready #safety .trust > .is-in { transition: opacity .8s var(--ease) var(--d, 0s), transform .8s var(--ease) var(--d, 0s), background-color var(--t2) var(--ease); }
html.reveal-ready #safety .trust > :not(.is-in) .trust-ic { opacity: 0; transform: scale(.5) rotate(-30deg); transition: none; }
html.reveal-ready #safety .trust > .is-in .trust-ic { transition: opacity .6s var(--ease) calc(var(--d, 0s) + .25s), transform .8s var(--ease) calc(var(--d, 0s) + .25s); }
@media (hover: hover) and (pointer: fine) and (min-width: 1024px) {
  html.motion #safety .sf .trust > .is-in:hover { transform: translate3d(0, -4px, 0); background: rgb(255 255 255 / .11); }
}

/* ============================================================ compare: the rows land one by one; on each row the TrustPay
   side fills from the left over the plain cell and its tick turns in, so "lock first" wins row after row */
html.reveal-ready #compare .cmp-wrap:not(.is-in) tbody tr { opacity: 0; transform: translate3d(0, 16px, 0); }
html.reveal-ready #compare .cmp-wrap.is-in tbody tr { transition: opacity .7s var(--ease) var(--rd, 0s), transform .7s var(--ease) var(--rd, 0s); }
#compare .cmp tbody tr:nth-child(1) { --rd: .1s; } #compare .cmp tbody tr:nth-child(2) { --rd: .32s; }
#compare .cmp tbody tr:nth-child(3) { --rd: .54s; } #compare .cmp tbody tr:nth-child(4) { --rd: .76s; }
html.reveal-ready #compare .cmp tbody td.cmp-tp { position: relative; isolation: isolate; background: var(--ground-2); }
html.reveal-ready #compare .cmp tbody td.cmp-tp::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--brand-soft); transform-origin: 0 50%; transform: scaleX(0); }
html.reveal-ready #compare .cmp-wrap.is-in tbody td.cmp-tp::before { transform: none; transition: transform .9s var(--ease) calc(var(--rd, 0s) + .3s); }
html.reveal-ready #compare .cmp td.cmp-tp .i { transform: scale(0) rotate(-45deg); }
html.reveal-ready #compare .cmp-wrap.is-in td.cmp-tp .i { transform: none; transition: transform .6s var(--ease) calc(var(--rd, 0s) + .75s); }

/* once a reveal has played, site.js drops its stagger delay (--d) and adds .is-settled ~1.4 s after .is-in, so hover in
   and out answer at once (the icons' own .22 s lag goes too) */
html.reveal-ready #features .ft-card.is-settled i, html.reveal-ready #safety .trust > .is-settled .trust-ic { transition-delay: 0s; }
