/* Layer-rise assembly: a fake app screen builds itself layer by layer, then a cursor glides in, presses,
   a checkbox fills and draws its tick, the row lifts onto a shadow and a name tag pops on the cursor.
   Everything waits for .is-live on the root (part.js adds it when the scene reaches the middle of the
   screen, once) and then holds its last frame.

   Classes (put them on your own markup):
   .lra                 root (scene). Gets .is-live.
   .lra-rise            a layer: rises 16px out of a 2px blur. Stagger with style="--lra-d: .15s".
   .lra-pop             a layer that pops (notification, toast): up 10px from scale .94 with an overshoot.
   .lra-hot             the row the cursor clicks (sits above its neighbours so its shadow shows).
     .lra-lift          inside it: the raised card behind the row's content (tint + shadow).
     .lra-check         the checkbox that gets checked; holds <svg class="lra-tick"><path .../></svg>.
     .lra-cursor        the cursor, absolutely placed so its tip lands on the target; holds the arrow
                        (.lra-arrow) and an optional name tag (.lra-tag).

   Measured from the source (Decimals how-it-works, scene 2):
   rise    .65s cubic-bezier(.2,.7,.3,1): 0% opacity 0, translateY(16px), blur(2px) / 70% opacity 1,
           translateY(-2px), blur(0) / 100% rest. Frame at 0s, rows at .15s + .08s each.
   cursor  arrives .85s cubic-bezier(.25,.7,.3,1) at .6s from (96px, 72px): visible by 35%, at (26px, 12px)
           by 60%; press .35s ease at 1.55s (40%: translate(1px,1px) scale(.92)).
   check   box fills .15s cubic-bezier(.22,1,.36,1) at 1.6s; tick draws (dashoffset 16 -> 0) .35s at 1.7s.
   row     raised copy fades in .2s at 1.6s, 4px high; settles .6s cubic-bezier(.3,.7,.3,1) at 1.9s while
           its shadow grows to 0 32px 32px rgba(78,70,55,.14), 0 5px 2.5px rgba(78,70,55,.04).
   tag     pops .35s cubic-bezier(.34,1.36,.64,1) at 2.1s, scale .6 -> 1 from its top-left (10px 0).
   pop     .65s cubic-bezier(.34,1.4,.5,1), translateY(10px) scale(.94) -> rest.
   Eases are literals: var() is ignored for a keyframe's timing function. */

.lra {
  --lra-rise-y: 16px;
  --lra-blur: 2px;
  --lra-rise-dur: 0.65s;
  --lra-cursor-at: 0.6s;
  --lra-cursor-dur: 0.85s;
  --lra-cursor-x: 96px;
  --lra-cursor-y: 72px;
  --lra-press-at: 1.55s;
  --lra-check-at: 1.6s;
  --lra-tick-at: 1.7s;
  --lra-lift-at: 1.9s;
  --lra-tag-at: 2.1s;
  --lra-ink: #2b2a27;                 /* checked box fill */
  --lra-tint: #f7f6f3;                /* raised row background */
  --lra-shadow: 0 32px 32px rgba(78, 70, 55, 0.14), 0 5px 2.5px rgba(78, 70, 55, 0.04);
  position: relative;
}

/* ---------- layers ---------- */
.lra-rise,
.lra-pop { opacity: 0; }

.lra.is-live .lra-rise {
  animation: lra-rise var(--lra-rise-dur) cubic-bezier(0.2, 0.7, 0.3, 1) var(--lra-d, 0s) both;
}
.lra.is-live .lra-pop {
  animation: lra-pop 0.65s cubic-bezier(0.34, 1.4, 0.5, 1) var(--lra-d, 0s) both;
}

@keyframes lra-rise {
  0% { opacity: 0; transform: translateY(var(--lra-rise-y)); filter: blur(var(--lra-blur)); }
  70% { opacity: 1; transform: translateY(-2px); filter: blur(0); }
  100% { opacity: 1; transform: none; filter: none; }
}
@keyframes lra-pop {
  from { opacity: 0; transform: translateY(10px) scale(0.94); }
  to { opacity: 1; transform: none; }
}

/* ---------- the clicked row ---------- */
.lra-hot { position: relative; z-index: 2; }
.lra-hot > :not(.lra-lift):not(.lra-cursor) { position: relative; z-index: 1; }
.lra-lift {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background: var(--lra-tint);
  opacity: 0;
  pointer-events: none;
}
/* the raised copy appears 4px high (row-in), then settles while its shadow grows (lift).
   lift fills forwards only, so it never overrides row-in before it starts. */
.lra.is-live .lra-lift {
  animation:
    lra-row-in 0.2s ease var(--lra-check-at) both,
    lra-row-lift 0.6s cubic-bezier(0.3, 0.7, 0.3, 1) var(--lra-lift-at) forwards;
}
/* the row's own content rides with the raised copy (it IS the copy in the source) */
.lra.is-live .lra-hot > :not(.lra-lift):not(.lra-cursor) {
  animation:
    lra-ride-in 0.2s ease var(--lra-check-at) both,
    lra-ride 0.6s cubic-bezier(0.3, 0.7, 0.3, 1) var(--lra-lift-at) forwards;
}
@keyframes lra-row-in {
  from { opacity: 0; translate: 0 0; box-shadow: 0 0 0 rgba(78, 70, 55, 0), 0 0 0 rgba(78, 70, 55, 0); }
  to { opacity: 1; translate: 0 -4px; box-shadow: 0 0 0 rgba(78, 70, 55, 0), 0 0 0 rgba(78, 70, 55, 0); }
}
@keyframes lra-row-lift {
  from { opacity: 1; translate: 0 -4px; box-shadow: 0 0 0 rgba(78, 70, 55, 0), 0 0 0 rgba(78, 70, 55, 0); }
  to { opacity: 1; translate: 0 0; box-shadow: var(--lra-shadow); }
}
@keyframes lra-ride-in { from { translate: 0 0; } to { translate: 0 -4px; } }
@keyframes lra-ride { from { translate: 0 -4px; } to { translate: 0 0; } }

/* ---------- checkbox + tick ---------- */
.lra-check {
  flex: none;
  width: 20px;
  height: 20px;
  border: 1px solid #d5d7da;
  border-radius: 6px;
  background: #fff;
  display: inline-grid;
  place-items: center;
  position: relative;
}
.lra-tick { width: 10px; height: 10px; overflow: visible; }
.lra-tick path {
  fill: none;
  stroke: #fff;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 16;
  stroke-dashoffset: 16;
}
.lra.is-live .lra-hot .lra-check {
  animation: lra-box-fill 0.15s cubic-bezier(0.22, 1, 0.36, 1) var(--lra-check-at) both;
}
.lra.is-live .lra-hot .lra-tick path {
  animation: lra-tick-draw 0.35s cubic-bezier(0.22, 1, 0.36, 1) var(--lra-tick-at) both;
}
@keyframes lra-box-fill { to { background: var(--lra-ink); border-color: var(--lra-ink); } }
@keyframes lra-tick-draw { from { stroke-dashoffset: 16; } to { stroke-dashoffset: 0; } }

/* ---------- cursor ---------- */
.lra-cursor {
  position: absolute;
  z-index: 3;
  width: 24px;
  height: 24px;
  opacity: 0;
  pointer-events: none;
}
.lra-arrow { display: block; width: 24px; height: 24px; transform-origin: 4px 3px; }
/* glide on the wrapper, press on the arrow: two elements, so neither cancels the other */
.lra.is-live .lra-cursor {
  animation: lra-cursor-in var(--lra-cursor-dur) cubic-bezier(0.25, 0.7, 0.3, 1) var(--lra-cursor-at) both;
}
.lra.is-live .lra-arrow {
  animation: lra-press 0.35s ease var(--lra-press-at) both;
}
@keyframes lra-cursor-in {
  0% { opacity: 0; transform: translate(var(--lra-cursor-x), var(--lra-cursor-y)); }
  35% { opacity: 1; }
  60% { transform: translate(calc(var(--lra-cursor-x) * 0.27), calc(var(--lra-cursor-y) * 0.17)); }
  100% { opacity: 1; transform: none; }
}
@keyframes lra-press {
  0%, 100% { transform: none; }
  40% { transform: translate(1px, 1px) scale(0.92); }
}

.lra-tag {
  position: absolute;
  top: 15px;
  left: 16px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--lra-ink);
  color: #fff;
  font: 500 12px/18px ui-sans-serif, system-ui, -apple-system, sans-serif;
  white-space: nowrap;
  opacity: 0;
  transform-origin: 10px 0;
}
.lra.is-live .lra-tag {
  animation: lra-tag-pop 0.35s cubic-bezier(0.34, 1.36, 0.64, 1) var(--lra-tag-at) both;
}
@keyframes lra-tag-pop {
  from { opacity: 0; transform: scale(0.6); }
  to { opacity: 1; transform: none; }
}

/* ---------- reduced motion: the finished scene, still ---------- */
@media (prefers-reduced-motion: reduce) {
  .lra .lra-rise, .lra .lra-pop, .lra .lra-cursor, .lra .lra-tag, .lra .lra-lift { opacity: 1; animation: none !important; }
  .lra .lra-lift { box-shadow: var(--lra-shadow); }
  .lra .lra-arrow, .lra .lra-hot > * { animation: none !important; }
  .lra .lra-hot .lra-check { background: var(--lra-ink); border-color: var(--lra-ink); animation: none !important; }
  .lra .lra-hot .lra-tick path { stroke-dashoffset: 0; animation: none !important; }
}
