/*
 * Showpieces: the four ready-made scroll effects (proper/parts/README.md,
 * "Showpieces"). Each is a good still section first; showpieces.js adds
 * `sp-on` when GSAP and ScrollTrigger are on the page and the visitor has not
 * asked for less motion, and only then does it hold and play.
 *
 * Only transform and opacity ever move. The held sections use position:
 * sticky, so no ancestor of a showpiece may have `overflow: hidden` or
 * `overflow: auto` (use `overflow-x: clip` to stop sideways scroll instead).
 *
 * Colours and type come from the parts' settings (--p-*), so a page themed for
 * parts.css is themed for these too. Add your own rules after this file.
 */
.sp-story, .sp-story *, .sp-assemble, .sp-assemble *, .sp-explode, .sp-explode *, .sp-words, .sp-words * { box-sizing: border-box; }

/* ===================== 1. Scroll story ===================== */
/* Still: the scenes one under another, each picture with its caption. */
.sp-story { position: relative; color: var(--p-text, #1A1F27); font-family: var(--p-font, inherit); }
.sp-story-stage { display: grid; gap: clamp(16px, 3vw, 32px); }
.sp-scene { position: relative; margin: 0; overflow: hidden; border-radius: var(--sp-radius, 0); background: #0B0C0E; }
.sp-scene img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.sp-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: grid; gap: 6px; padding: clamp(20px, 4vw, 56px);
  color: #FFFFFF;
  background: linear-gradient(to top, rgba(0, 0, 0, .72), rgba(0, 0, 0, .38) 55%, transparent);
}
.sp-num { font-size: .8125rem; font-weight: 600; letter-spacing: .14em; opacity: .85; }
.sp-num::after { content: ""; display: block; width: 40px; height: 1px; margin-top: 10px; background: currentColor; opacity: .7; }
.sp-title { display: block; max-width: 18ch; font-size: clamp(1.75rem, 5.2vw, 4.5rem); font-weight: 700; line-height: 1; letter-spacing: -.02em; }
.sp-line { display: block; max-width: 46ch; font-size: clamp(1rem, 1.4vw, 1.1875rem); line-height: 1.45; opacity: .92; }
.sp-count { display: none; }
@media (max-width: 759px) {
  .sp-scene img { aspect-ratio: 4 / 5; }
}

/* Playing: one held screen, the scenes cross-fading in place with a slow push-in. */
.sp-story.sp-on { height: calc((var(--sp-n, 4) * 75 + 25) * 1svh); }
.sp-story.sp-on .sp-story-stage { position: sticky; top: 0; display: block; height: 100svh; overflow: hidden; background: #0B0C0E; }
.sp-story.sp-on .sp-scene { position: absolute; inset: 0; border-radius: 0; isolation: isolate; }
.sp-story.sp-on .sp-scene img { width: 100%; height: 100%; aspect-ratio: auto; transform-origin: 50% 55%; will-change: transform; }
.sp-story.sp-on .sp-scene + .sp-scene { opacity: 0; }
.sp-story.sp-on .sp-cap { padding-bottom: clamp(56px, 9vh, 96px); will-change: transform, opacity; }
.sp-story.sp-on .sp-count {
  display: block; position: absolute; z-index: 5; right: clamp(16px, 3vw, 40px); bottom: clamp(20px, 4vh, 40px);
  color: #FFFFFF; font-size: .8125rem; font-weight: 600; letter-spacing: .14em; font-variant-numeric: tabular-nums;
}
.sp-story.sp-on .sp-count b { font-weight: 700; }

/* ===================== 2. Builds itself ===================== */
/* Still: the steps beside the finished picture, every piece in place. */
.sp-assemble { position: relative; color: var(--p-text, #1A1F27); font-family: var(--p-font, inherit); }
.sp-as-stage {
  display: grid; gap: clamp(24px, 4vw, 56px); align-items: center;
  grid-template-columns: minmax(0, 1fr);
  padding: clamp(24px, 5vw, 64px) clamp(16px, 4vw, 48px);
}
@media (min-width: 900px) { .sp-as-stage { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); } }
.sp-as-copy h2 { margin: 0 0 18px; font-size: clamp(1.75rem, 3.6vw, 3rem); line-height: 1.05; letter-spacing: -.02em; }
.sp-as-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; counter-reset: sp-step; }
.sp-as-steps li {
  counter-increment: sp-step;
  display: grid; grid-template-columns: 2.4em 1fr; column-gap: 10px;
  padding: 10px 0; border-top: 1px solid var(--p-line, rgba(20, 24, 31, .14));
  transition: color .25s ease, opacity .25s ease;
}
.sp-as-steps li::before { content: counter(sp-step, decimal-leading-zero); grid-row: span 2; font-size: .8125rem; font-weight: 700; letter-spacing: .08em; color: var(--p-accent, #0F5FA8); padding-top: .2em; }
.sp-as-steps b { font-size: 1.0625rem; }
.sp-as-steps span { color: var(--p-muted, #5A6472); font-size: .9375rem; line-height: 1.45; }

.sp-as-frame {
  position: relative; border-radius: 14px; overflow: hidden;
  background: var(--sp-site-ground, #FFFFFF); color: #1A1F27;
  border: 1px solid var(--p-line, rgba(20, 24, 31, .14));
  box-shadow: 0 30px 60px -30px rgba(10, 15, 30, .45);
}
.sp-as-bar { position: relative; z-index: 2; display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: #ECEEF1; border-bottom: 1px solid rgba(0, 0, 0, .08); }
.sp-as-dots { display: inline-flex; gap: 6px; }
.sp-as-dots i { width: 10px; height: 10px; border-radius: 50%; background: #C9CDD3; }
.sp-as-address {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px; background: #FFFFFF; color: #3A414B;
  font-size: .8125rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sp-as-address svg { flex: none; }
.sp-as-done {
  flex: none; padding: 3px 10px; border-radius: 999px; background: #1E7A4C; color: #FFFFFF;
  font-size: .75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.sp-as-site { display: grid; gap: 0; }
.sp-as-piece { position: relative; }

/* Playing: held; pieces arrive one per step, the current step lights up. */
.sp-assemble.sp-on { height: calc((var(--sp-n, 5) * 60 + 40) * 1svh); }
.sp-assemble.sp-on .sp-as-stage { position: sticky; top: 0; min-height: 100svh; align-content: center; }
.sp-assemble.sp-on .sp-as-steps li { opacity: .38; }
.sp-assemble.sp-on .sp-as-steps li.is-on { opacity: 1; }
.sp-assemble.sp-on .sp-as-steps li.is-now b { color: var(--p-accent, #0F5FA8); }
.sp-assemble.sp-on .sp-as-frame { justify-self: center; width: 100%; }
/* A faint drawing grid under the pieces while it is being built, gone once it is live. */
.sp-assemble.sp-on .sp-as-site { position: relative; }
.sp-assemble.sp-on .sp-as-site::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; transition: opacity .5s ease;
  background:
    linear-gradient(to bottom, transparent calc(100% - 1px), rgba(20, 60, 140, .07) 0) 0 0 / 100% 24px,
    linear-gradient(to right, transparent calc(100% - 1px), rgba(20, 60, 140, .07) 0) 0 0 / 24px 100%;
}
.sp-assemble.sp-on.is-done .sp-as-site::before { opacity: 0; }
/* data-follow: a one-screen window whose page scrolls to each piece as it lands.
   --sp-follow-ratio sets the window's shape (a phone by default). Still, it
   shows the top of the finished page. */
.sp-assemble .sp-as-frame[data-follow] { display: flex; flex-direction: column; max-width: 360px; justify-self: center; }
.sp-assemble .sp-as-frame[data-follow] .sp-as-site { flex: none; }
.sp-assemble:not(.sp-on) .sp-as-frame[data-follow] { max-height: min(80svh, 760px); }
.sp-assemble.sp-on .sp-as-frame[data-follow] { aspect-ratio: var(--sp-follow-ratio, 9 / 17); }
.sp-assemble.sp-on .sp-as-frame[data-follow] .sp-as-site { will-change: transform; }
.sp-assemble.sp-on .sp-as-piece { will-change: transform, opacity; }
.sp-assemble.sp-on .sp-as-done { opacity: 0; transform: scale(.8); transition: opacity .3s ease, transform .3s cubic-bezier(.23, 1, .32, 1); }
.sp-assemble.sp-on.is-done .sp-as-done { opacity: 1; transform: none; }
@media (max-width: 899px) {
  /* On a phone the held screen shows the frame and only the step being built. */
  .sp-assemble.sp-on .sp-as-stage { gap: 16px; padding-top: 72px; padding-bottom: 24px; }
  .sp-assemble.sp-on .sp-as-copy h2 { margin-bottom: 8px; font-size: clamp(1.5rem, 6.4vw, 2rem); }
  .sp-assemble.sp-on .sp-as-steps { position: relative; display: block; min-height: 4.6em; }
  .sp-assemble.sp-on .sp-as-steps li { position: absolute; top: 0; left: 0; right: 0; visibility: hidden; border-top: 0; padding: 4px 0 0; }
  .sp-assemble.sp-on .sp-as-steps li.is-now { position: relative; visibility: visible; }
}

/* ===================== 3. Comes apart ===================== */
/* Still: each layer with its name beside it, top to bottom. */
.sp-explode { position: relative; color: var(--p-text, #1A1F27); font-family: var(--p-font, inherit); }
.sp-ex-stage { display: grid; gap: clamp(24px, 4vw, 56px); align-items: center; padding: clamp(24px, 5vw, 64px) clamp(16px, 4vw, 48px); }
@media (min-width: 900px) { .sp-ex-stage { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); } }
.sp-ex-copy h2 { margin: 0 0 12px; font-size: clamp(1.75rem, 3.6vw, 3rem); line-height: 1.05; letter-spacing: -.02em; }
.sp-ex-copy p { margin: 0; max-width: 40ch; color: var(--p-muted, #5A6472); line-height: 1.55; }
.sp-ex-stack { display: grid; gap: 14px; }
.sp-ex-layer { margin: 0; display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; align-items: center; }
.sp-ex-plate {
  aspect-ratio: 16 / 10; border-radius: 10px; overflow: hidden;
  background: var(--sp-plate, var(--p-raised, #F3F5F8));
  border: 1px solid var(--p-line, rgba(20, 24, 31, .14));
}
.sp-ex-plate img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sp-ex-label b { display: block; font-size: 1.0625rem; }
.sp-ex-label span { display: block; color: var(--p-muted, #5A6472); font-size: .9375rem; line-height: 1.45; }
.sp-ex-label b::before { content: ""; display: inline-block; width: 18px; height: 1px; margin: 0 8px .3em 0; vertical-align: middle; background: var(--p-accent, #0F5FA8); }

/* Playing: the layers sit as one stacked, tilted object, spread apart with
   their names, then close up again. The tilt is set once on the plate; only
   the layer's position and the label's fade move. */
.sp-explode.sp-on { height: calc((var(--sp-n, 4) * 45 + 100) * 1svh); }
.sp-explode.sp-on .sp-ex-stage { position: sticky; top: 0; min-height: 100svh; align-content: center; }
.sp-explode.sp-on .sp-ex-stack { position: relative; display: block; height: min(78svh, 720px); }
.sp-explode.sp-on .sp-ex-layer {
  position: absolute; left: 0; right: 0; top: 50%;
  display: block; height: 0; will-change: transform;
}
.sp-explode.sp-on .sp-ex-plate {
  position: absolute; left: 2%; width: min(52%, 460px); top: 0;
  transform: perspective(1600px) translateY(-50%) rotateX(56deg) rotateZ(-36deg);
  border-radius: 14px;
  box-shadow: 0 40px 50px -30px rgba(0, 0, 0, .45);
}
.sp-explode.sp-on .sp-ex-label {
  /* A zero-height box centres the label on the layer's line without a transform,
     so the script is free to move it. */
  position: absolute; left: 63%; right: 0; top: 0; height: 0;
  display: flex; flex-direction: column; justify-content: center;
  opacity: 0; will-change: opacity, transform;
}
@media (max-width: 899px) {
  .sp-explode.sp-on .sp-ex-stage { gap: 8px; padding-top: 72px; }
  .sp-explode.sp-on .sp-ex-copy p { display: none; }
  .sp-explode.sp-on .sp-ex-stack { height: 70svh; }
  .sp-explode.sp-on .sp-ex-plate { left: 3%; width: 50%; }
  .sp-explode.sp-on .sp-ex-label { left: 61%; }
  .sp-explode.sp-on .sp-ex-label span { display: none; }
  .sp-explode.sp-on .sp-ex-label b { font-size: .9375rem; }
}

/* ===================== 4. Giant words ===================== */
/* Still: the words as one big wrapped list. */
.sp-words { position: relative; overflow-x: clip; padding: clamp(32px, 6vw, 96px) 0; color: var(--p-text, #1A1F27); font-family: var(--sp-words-font, var(--p-font, inherit)); }
.sp-words-list {
  list-style: none; margin: 0; padding: 0 clamp(16px, 4vw, 48px);
  display: flex; flex-wrap: wrap; gap: 0 .35em;
  font-size: clamp(2.75rem, 9vw, 8rem); font-weight: 800; line-height: .98; letter-spacing: -.035em; text-transform: var(--sp-words-case, none);
}
.sp-words-list li:nth-child(3n + 2) { color: var(--p-accent, #0F5FA8); }
.sp-words-rows { display: none; }

/* Playing: three rows of the same words, each sliding its own way and speed. */
.sp-words.sp-on .sp-words-list { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; padding: 0; }
.sp-words.sp-on .sp-words-rows { display: grid; gap: .04em; font-size: clamp(3.5rem, 12vw, 11rem); font-weight: 800; line-height: 1; letter-spacing: -.035em; text-transform: var(--sp-words-case, none); }
.sp-words-row { display: flex; width: max-content; white-space: nowrap; will-change: transform; }
.sp-words-row span { padding-right: .32em; }
.sp-words-row span::after { content: "\00B7"; padding-left: .32em; opacity: .35; }
.sp-words-row:nth-child(2) { color: transparent; -webkit-text-stroke: 1.5px var(--p-text, #1A1F27); }
.sp-words-row:nth-child(3) { color: var(--p-accent, #0F5FA8); }
@supports not (-webkit-text-stroke: 1px black) { .sp-words-row:nth-child(2) { color: var(--p-muted, #5A6472); } }
