/* The pile. Cards drop in one at a time as you scroll and stay where they
   land, building a deliberate arrangement.

   Two rules make it feel real:
   1. z-index is fixed per card and never changes, so no card ever passes
      through another one.
   2. Nothing fades. A card is either above the frame or on the pile.
      The only state change is a transform.

   The resting angle and offset of each card are preset per index, so the
   arrangement looks casual but lands identically every time. */

.dp{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.6rem,4vw,3.4rem);align-items:start}
.dp__stage{position:sticky;top:var(--dp-top,96px)}
.dp__rows{display:grid}
.dp__row{min-height:var(--dp-row,66vh);display:flex;flex-direction:column;justify-content:center;
  padding:1.6rem 0;opacity:.36;transition:opacity .35s ease}
.dp__row.on{opacity:1}
/* the first block starts level with the top of the mat instead of floating
   mid-row, so text and mat begin together */
.dp__row:first-child{justify-content:flex-start;padding-top:14px}
.dp__row h3{font-size:clamp(1.5rem,3vw,2.15rem)}
.dp__row p{color:var(--text-muted);margin-top:.65rem;max-width:40ch;font-size:1.02rem}
.dp__kicker{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--c);font-weight:500}
.dp__bar{width:46px;height:5px;border-radius:3px;background:var(--c);margin-bottom:.9rem;
  transform-origin:left;transform:scaleX(.28);transition:transform .4s ease}
.dp__row.on .dp__bar{transform:scaleX(1)}
.dp__bul{list-style:none;margin:1rem 0 0;padding:0;display:grid;gap:.4rem}
.dp__bul li{display:flex;gap:.55rem;align-items:flex-start;font-size:.94rem;color:var(--text-muted)}
.dp__bul li::before{content:'';width:8px;height:8px;border-radius:50%;background:var(--c);
  flex:0 0 auto;margin-top:.42rem}

/* ---------- the pile ---------- */
.pile{position:relative;aspect-ratio:1/1;border-radius:16px;perspective:1200px}
.pile__inner{position:absolute;inset:0}

.pc{position:absolute;left:50%;top:50%;translate:-50% -50%;
  width:80%;aspect-ratio:5/3;                       /* a 3 by 5 index card */
  border-radius:14px;background:var(--c);
  box-shadow:0 4px 10px rgba(30,25,20,.20), 0 18px 34px rgba(30,25,20,.16);
  transform:translate3d(var(--dx), var(--dy), 0) rotate(var(--rot));
  will-change:transform}
.pc__card{position:absolute;inset:10px;background:#fff;border-radius:8px;overflow:hidden;
  display:flex;box-shadow:0 2px 5px rgba(30,25,20,.18)}
.pc__art{flex:0 0 auto;height:100%;aspect-ratio:1;background:var(--paper-card)}
.pc__art img,.pc__art video{width:100%;height:100%;object-fit:cover;display:block}
.pc__meta{flex:1;min-width:0;padding:.75rem .9rem;display:flex;flex-direction:column;
  justify-content:center;
  /* faint rules, the way an index card is printed */
  background-image:repeating-linear-gradient(transparent 0 21px, rgba(77,150,255,.16) 21px 22px);
  background-position:0 6px}
.pc__name{font-family:var(--font-display);font-weight:800;font-size:1.02rem;line-height:1.2}
.pc__sub{font-size:.78rem;color:var(--text-muted);line-height:1.35;margin-top:.25rem;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* above the frame, waiting to fall. No opacity anywhere. */
.pc{visibility:visible}

/* .out = flying off, still on screen. Visibility flips only at the END of
   the flight, so you watch the whole thing leave. */
.pc.out{visibility:hidden;
  transform:translate3d(var(--dx), calc(var(--dy) - 165%), 0)
            rotate(calc(var(--rot) + var(--spin) * .9))}

/* .up = parked above the window, hidden, and moved there with no
   transition, so nothing is ever seen waiting. */
.pc.up{visibility:hidden;transition:none !important;
  transform:translate3d(var(--dx), calc(var(--dy) - 70vh - 120%), 0)
            rotate(calc(var(--rot) + var(--spin)))}

/* ---------- three drop feels ---------- */
/* spring: lands, overshoots a touch, settles */
.f-spring .pc{transition:transform .78s cubic-bezier(.16,1.3,.34,1) var(--delay,0s),
                            visibility 0s linear var(--delay,0s)}
.f-spring .pc.out{transition:transform .52s cubic-bezier(.42,0,.78,.4) var(--delay,0s),
                                visibility 0s linear calc(.52s + var(--delay,0s))}

/* soft: same drop, no overshoot */
.f-soft .pc{transition:transform .7s cubic-bezier(.2,.88,.26,1) var(--delay,0s),
                          visibility 0s linear var(--delay,0s)}
.f-soft .pc.out{transition:transform .52s cubic-bezier(.42,0,.78,.4) var(--delay,0s),
                              visibility 0s linear calc(.52s + var(--delay,0s))}

/* toss: comes in from the side with more spin */
.f-toss .pc{transition:transform .82s cubic-bezier(.16,1.26,.34,1) var(--delay,0s),
                          visibility 0s linear var(--delay,0s)}
.f-toss .pc.out{transition:transform .55s cubic-bezier(.42,0,.78,.4) var(--delay,0s),
                              visibility 0s linear calc(.55s + var(--delay,0s))}
.f-toss .pc.up{transform:translate3d(calc(var(--dx) + 120%), calc(var(--dy) - 70vh - 120%), 0)
                         rotate(calc(var(--rot) + var(--spin) * 2.4))}
.f-toss .pc.out{transform:translate3d(calc(var(--dx) + 130%), calc(var(--dy) - 105%), 0)
                          rotate(calc(var(--rot) + var(--spin) * 2.2))}

/* the pile takes the hit when a card lands */
.pile.hit .pile__inner{animation:pileHit .26s ease}
@keyframes pileHit{0%{transform:translateY(0)}35%{transform:translateY(4px)}
                   70%{transform:translateY(-1px)}100%{transform:translateY(0)}}

/* ---------- the surface the cards land on ----------
   The stage is a real panel, so on a phone the text scrolls under
   something solid instead of disappearing behind nothing. */
.mat.surf{border-radius:24px;padding:14px;
  box-shadow:0 2px 6px rgba(30,25,20,.16), 0 18px 40px rgba(30,25,20,.14)}

/* self-healing cutting mat: the craft-room surface */
.s-mat{background-color:#24443C;
  background-image:
    linear-gradient(rgba(255,255,255,.30) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.30) 1px, transparent 1px),
    linear-gradient(rgba(255,255,255,.10) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.10) 1px, transparent 1px);
  background-size:120px 120px, 120px 120px, 24px 24px, 24px 24px}

/* deep board: solid, no grid, colour only */
.s-board{background-color:#1F3350;
  background-image:radial-gradient(rgba(255,255,255,.16) 1.4px, transparent 1.5px);
  background-size:22px 22px}

/* light graph panel, the site's own paper */
.s-paper{background-color:#FBFCFE;
  background-image:
    linear-gradient(rgba(77,150,255,.16) 1px, transparent 1px),
    linear-gradient(90deg, rgba(77,150,255,.16) 1px, transparent 1px),
    radial-gradient(rgba(77,150,255,.34) 1.6px, transparent 1.7px);
  background-size:24px 24px, 24px 24px, 96px 96px;
  box-shadow:0 2px 6px rgba(30,25,20,.10), 0 16px 34px rgba(30,25,20,.10)}

/* nothing: cards float on the page */
.s-none{background:none;box-shadow:none;padding:0}

@media (prefers-reduced-motion: reduce){
  .pc{transition:none}
  .pile.hit .pile__inner{animation:none}
}

@media (max-width:820px){
  .dp{grid-template-columns:1fr;gap:.6rem}
  /* an opaque white band carries the mat, so nothing shows through above
     or beside it, and the text fades out as it slides up underneath */
  .dp__stage{order:-1;position:sticky;top:0;z-index:20;background:#fff;
    margin-inline:calc(-1 * var(--gutter));padding:10px var(--gutter) 8px}
  .dp__stage::after{content:'';position:absolute;left:0;right:0;top:100%;height:26px;
    pointer-events:none;
    background:linear-gradient(#fff 0%, rgba(255,255,255,.72) 40%, rgba(255,255,255,0) 100%)}
  .mat.surf{border-radius:14px;padding:8px;
    box-shadow:0 6px 14px -8px rgba(30,25,20,.40)}
  .mat.s-none{background:#fff;box-shadow:none}
  .pile{aspect-ratio:auto;height:32vh;max-height:280px;border-radius:10px}
  .pc{width:auto;height:64%}
  /* the band is wide and short, so a sideways toss can still be on screen
     while it waits. Everything falls straight down here instead. */
  .f-toss .pc.up{transform:translate3d(var(--dx), calc(var(--dy) - 70vh - 120%), 0)
                           rotate(calc(var(--rot) + var(--spin)))}
  .dp__row{min-height:0;padding:1.3rem 0;opacity:1}
  .dp__row:first-child{padding-top:1.3rem}
  .dp__row + .dp__row{border-top:1px solid var(--line)}
}
