/* Scroll moments. Loads after styles.css. Motion always runs, there is no
   reduced motion switch on purpose (Mark's call). Transform and opacity only. */

:root { --stage-h: calc(100svh - 64px - var(--bar)); }

/* ---------- Hero: deck photo in layers ---------- */
.hero-layers { position: absolute; inset: 0; overflow: hidden; }
.hero-layers picture { position: absolute; inset: 0; display: block; will-change: transform; }
.hero-layers img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; object-position: 60% 60%; }
.hero-back { transform-origin: 50% 40%; }
.hero-fore { transform-origin: 60% 100%; animation: foreSettle 1.6s cubic-bezier(.2,.7,.2,1) both; }
.hero-shade {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,.15) 0%, rgba(0,0,0,.25) 40%, rgba(0,0,0,.85) 100%);
}
@keyframes foreSettle { from { translate: 0 40px; scale: 1.05; } to { translate: 0 0; scale: 1; } }

.build-lines .ln { display: inline-block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; vertical-align: top; }
.build-lines .ln > span { display: inline-block; animation: lineUp .9s cubic-bezier(.2,.75,.2,1) var(--d, 0s) both; }
@keyframes lineUp { from { transform: translateY(105%); } to { transform: translateY(0); } }
.hero-in { animation: fadeUp .8s cubic-bezier(.2,.75,.2,1) var(--d, 0s) both; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
.hero-text { will-change: transform, opacity; }

/* ---------- Pinned acts (only once the script is running) ---------- */
.js .act { padding: 0; }
.js .act > .stage {
  position: sticky; top: 64px; height: var(--stage-h); overflow: hidden;
  display: flex; flex-direction: column; justify-content: center;
}

/* ---------- Builds: job types slide in sideways ---------- */
.rail-view { overflow-x: auto; }
.js .act-pan .rail-view { overflow: visible; }
.rail {
  display: flex; gap: 12px; width: max-content; margin: 24px 0 0;
  padding: 0 20px; will-change: transform;
}
.rail li { width: min(68vw, 330px); flex: none; will-change: transform, opacity; }
.js .act-pan .wrap h2 { margin-bottom: 0; }
@media (min-width: 900px) {
  .rail { padding: 0 max(32px, calc((100vw - 1140px) / 2 + 32px)); gap: 16px; }
  .rail li { width: clamp(240px, calc((var(--stage-h) - 200px) * .8), 460px); }
}

/* ---------- Before and after: the big moment ---------- */
.js .act-ba .stage { justify-content: center; }
.js .act-ba h2 { margin-bottom: .3em; }
.js .act-ba .ba-grid { margin-top: 12px; display: flex; justify-content: center; gap: 28px; }
.js .act-ba .ba { flex: none; height: min(calc(var(--stage-h) - 190px), calc((100vw - 140px) * .48)); width: auto; transition: opacity .4s, filter .4s; }
.js .act-ba .ba.is-waiting { opacity: .5; filter: saturate(.6); }
.ba-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; background: rgba(255,255,255,.15); z-index: 2; pointer-events: none; }
.ba-bar i { display: block; height: 100%; width: 100%; background: var(--orange); transform-origin: 0 50%; transform: scaleX(0); }
@media (max-width: 899px) {
  .js .act-ba .ba-grid { position: relative; display: block; height: calc(var(--stage-h) - 170px); }
  .js .act-ba .ba {
    position: absolute; left: 50%; top: 0; translate: -50% 0;
    height: auto; width: min(100%, calc((var(--stage-h) - 170px) * var(--r)));
  }
  .js .act-ba .ba:nth-child(1) { --r: 1.3333; }
  .js .act-ba .ba:nth-child(2) { --r: .75; }
  .js .act-ba .ba.is-waiting { opacity: 0; pointer-events: none; }
}

/* ---------- Jobs: photos drift at different speeds ---------- */
.act-drift { overflow: hidden; }
.act-drift .gallery li { will-change: transform; }

/* ---------- Reviews: one at a time ---------- */
.reviews blockquote { will-change: transform, opacity; }
.js .act-reviews .reviews blockquote { opacity: 0; }

/* ---------- Dan: photo layers slower than the text ---------- */
.dan-photos { position: relative; aspect-ratio: 1; }
.dan-photos > * { will-change: transform; }
.dan-block { position: absolute; inset: 9% -4% -6% 12%; background: var(--orange); border-radius: var(--radius); }
.dan-truck { position: absolute; inset: 0 8% 8% 0; display: block; }
.dan-truck img { width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; border-radius: var(--radius); box-shadow: 0 18px 40px -18px rgba(0,0,0,.45); }
.dan-photos .dan-job {
  position: absolute; right: 0; bottom: -4%; width: 34%; height: auto; aspect-ratio: auto;
  border-radius: var(--radius); border: 5px solid var(--paper); box-shadow: 0 14px 30px -10px rgba(0,0,0,.5);
}

/* ---------- Questions and quote: calm fade in ---------- */
.js .rise { opacity: 0; transform: translateY(18px); transition: opacity .7s cubic-bezier(.2,.75,.2,1), transform .7s cubic-bezier(.2,.75,.2,1); }
.js .rise.in { opacity: 1; transform: none; }

/* ---------- The small thing that follows the mouse ---------- */
.follow { display: none; }
@media (hover: hover) and (pointer: fine) {
  .follow {
    display: block; position: fixed; left: 0; top: 0; z-index: 80; pointer-events: none;
    width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%;
    border: 2px solid var(--orange); opacity: 0;
    transition: opacity .25s, width .25s, height .25s, margin .25s, background-color .25s;
  }
  .follow.on { opacity: .9; }
  .follow.big { width: 64px; height: 64px; margin: -32px 0 0 -32px; background-color: rgba(247,146,58,.18); }
}

/* Phones: reviews are not pinned, each card comes in as it reaches you */
@media (max-width: 899px) {
  .js .act-reviews { padding: 64px 0; }
  .js .act-reviews > .stage { position: static; height: auto; overflow: visible; display: block; }
}

/* Placeholder until Dan sends a profile photo */
.dan-photos .dan-profile {
  aspect-ratio: 3/4; display: grid; place-items: center; text-align: center; padding: 10px;
  background: var(--char); color: var(--paper); font: 700 1rem/1.2 var(--head);
}
