/* Animated project previews: used by the project viewer on the home page and by /work pages. */
:root { --spring: cubic-bezier(.34, 1.56, .64, 1); --ease: cubic-bezier(.22, 1, .36, 1); }
.preview { position: relative; height: 300px; border-radius: 16px; overflow: hidden; background: var(--paper); border: 1.5px solid var(--line); }
/* timetable: cells fill themselves */
.tt-grid { position: absolute; inset: 18px; display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(6, 1fr); gap: 5px; }
.tt-grid i { border-radius: 5px; background: var(--line); transform: scale(.6); opacity: 0; }
.tt-grid i { animation: cell .45s var(--spring) forwards; animation-delay: calc(var(--n) * 45ms); }
@keyframes cell { to { transform: scale(1); opacity: 1; background: var(--c); } }

/* algo-tn: pseudocode -> python */
.pv-code { display: flex; flex-direction: column; justify-content: center; gap: 6px; padding: 18px 22px; background: #14151a; border-color: #14151a; }
.pv-code pre { margin: 0; font: 13px/1.55 ui-monospace, "Cascadia Code", Consolas, monospace; white-space: pre; overflow: hidden; }
.pv-code .code-in { color: #f3d27a; }
.pv-code .code-out { color: #8ee0a1; }
.pv-code .arrow { color: #8093ff; font-size: 22px; line-height: 1; transform: rotate(90deg); align-self: flex-start; margin-left: 30px; }
.pv-code .code-in { animation: type-in 1.4s steps(30) both; }
.pv-code .arrow { animation: pulse-x 1s ease-in-out 1.3s infinite; }
.pv-code .code-out { animation: type-in 1.4s steps(30) 1.5s both; }
@keyframes type-in { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes pulse-x { 50% { transform: rotate(90deg) translateX(5px); } }

/* interacta: a phone swiping through playable posts */
.pv-phone { display: grid; place-items: center; }
.phone { width: 140px; height: 260px; border: 3px solid var(--ink); border-radius: 26px; overflow: hidden; background: var(--card); position: relative; }
.phone::before { content: ""; position: absolute; top: 7px; left: 50%; width: 40px; height: 5px; margin-left: -20px; border-radius: 3px; background: var(--ink); z-index: 2; }
.feed { display: flex; flex-direction: column; animation: feed 8s var(--ease) infinite; }
.feed i { flex: none; height: 254px; display: grid; place-items: center; }
.feed i:nth-child(1) { background: linear-gradient(160deg, #2346ff, #8093ff); }
.feed i:nth-child(2) { background: linear-gradient(160deg, #ff5a4e, #ffc542); }
.feed i:nth-child(3) { background: linear-gradient(160deg, #29c46a, #1b7a45); }
.feed i:nth-child(4) { background: linear-gradient(160deg, #2346ff, #8093ff); }
.feed i::after { content: ""; width: 54px; height: 54px; border: 4px solid rgba(255, 255, 255, .9); border-radius: 12px; animation: spin 3s linear infinite; }
.feed i:nth-child(2)::after { border-radius: 50%; }
.feed i:nth-child(3)::after { border-radius: 0; transform: rotate(45deg); }
@keyframes feed { 0%, 20% { transform: translateY(0); } 33%, 53% { transform: translateY(-254px); } 66%, 86% { transform: translateY(-508px); } 100% { transform: translateY(-762px); } }
@keyframes spin { to { rotate: 360deg; } }

/* keep going: the red box rolls and jumps a gap */
.pv-box { background: linear-gradient(#dfe8f5, #f6f4ee); }
body.night .pv-box { background: linear-gradient(#1b2030, #0c0c0d); }
.pv-box .ground { position: absolute; left: 0; right: 0; bottom: 60px; height: 14px; display: flex; gap: 60px; }
.pv-box .ground i { flex: 1; background: var(--ink); border-radius: 3px; }
.pv-box .box { position: absolute; left: -40px; bottom: 74px; width: 34px; height: 34px; background: #e2504f; border-radius: 5px; box-shadow: inset -5px -5px 0 rgba(0, 0, 0, .18); animation: box-roll 4s linear infinite; }
@keyframes box-roll {
  0% { transform: translateX(0) rotate(0); }
  40% { transform: translateX(calc(var(--w, 440px) * .42)) rotate(360deg); }
  52% { transform: translateX(calc(var(--w, 440px) * .56)) translateY(-70px) rotate(450deg); }
  64% { transform: translateX(calc(var(--w, 440px) * .7)) rotate(540deg); }
  100% { transform: translateX(calc(var(--w, 440px) + 60px)) rotate(900deg); }
}

/* majdsub: a video with subtitles appearing */
.pv-video { background: #0a0a0c; border-color: #0a0a0c; display: grid; place-items: center; }
.pv-video .screen { position: relative; width: 86%; aspect-ratio: 16 / 9; border-radius: 8px; background: radial-gradient(ellipse at 40% 40%, #2a3350, #0d0f18 70%); overflow: hidden; }
.pv-video .screen::before { content: "▶"; position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%); color: rgba(255, 255, 255, .25); font-size: 34px; }
.pv-video .sub { position: absolute; left: 0; right: 0; bottom: 10%; text-align: center; color: #fff; font-size: 14px; text-shadow: 0 1px 3px #000; padding: 0 10px; }


/* pixel publisher: a page writes itself, then the market answers */
.pv-paper { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: center; padding: 20px; }
.pv-paper .sheet { height: 88%; padding: 18px 16px; background: var(--card); border: 1.5px solid var(--line); border-radius: 4px 10px 10px 4px; box-shadow: 4px 5px 0 -1px var(--line); display: flex; flex-direction: column; gap: 11px; }
.pv-paper .sheet i { height: 6px; border-radius: 3px; background: var(--ink); opacity: .75; width: 0; animation: pp-line 6s var(--ease) infinite; }
.pv-paper .sheet i:nth-child(2) { animation-delay: .35s; --to: 92%; }
.pv-paper .sheet i:nth-child(3) { animation-delay: .7s; --to: 78%; }
.pv-paper .sheet i:nth-child(4) { animation-delay: 1.05s; --to: 96%; }
.pv-paper .sheet i:nth-child(5) { animation-delay: 1.4s; --to: 55%; }
@keyframes pp-line { 0% { width: 0; } 18%, 85% { width: var(--to, 100%); } 100% { width: var(--to, 100%); opacity: 0; } }
.pv-paper .market { position: relative; height: 88%; }
.pv-paper .curve { position: absolute; inset: 0 0 30px; width: 100%; height: calc(100% - 30px); overflow: visible; }
.pv-paper .curve path { fill: none; stroke: #2346ff; stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 400; stroke-dashoffset: 400; animation: pp-curve 6s var(--ease) infinite; }
@keyframes pp-curve { 0%, 30% { stroke-dashoffset: 400; } 60%, 92% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 0; opacity: 0; } }
.pv-paper .stars { position: absolute; left: 0; bottom: 0; font-size: 22px; letter-spacing: 3px; color: #e0a800; opacity: 0; animation: pp-stars 6s var(--spring) infinite; }
@keyframes pp-stars { 0%, 55% { opacity: 0; transform: translateY(8px); } 65%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; } }

/* project studio: film rolls past a slate */
.pv-film { background: #070708; border-color: #070708; display: grid; align-items: center; }
.pv-film::before, .pv-film::after { content: ""; position: absolute; left: 0; right: 0; height: 14%; background: #000; z-index: 2; }
.pv-film::before { top: 0; } .pv-film::after { bottom: 0; }
.pv-film .strip { display: flex; gap: 10px; padding: 14px 0; width: max-content; background: #1a1a1d; border-block: 10px dashed #070708; animation: film 7s linear infinite; }
.pv-film .strip i { width: 120px; height: 84px; border-radius: 3px; background: linear-gradient(135deg, #2a3350, #6b4b2a); }
.pv-film .strip i:nth-child(3n) { background: linear-gradient(135deg, #3a1d1d, #b8412e); }
.pv-film .strip i:nth-child(3n+1) { background: linear-gradient(135deg, #1d3a2a, #5a8a3c); }
@keyframes film { to { transform: translateX(-520px); } }
.pv-film .slate { position: absolute; right: 14px; bottom: calc(14% + 10px); z-index: 3; font-family: var(--hand, cursive); font-size: 20px; color: #f3f1ea; background: #111; border: 1.5px solid #f3f1ea; border-radius: 4px; padding: 2px 10px; }

/* pivot: cards dealt onto the table */
.pv-cards { background: radial-gradient(ellipse at center, #1f5a3c, #0f2e1f 75%); border-color: #0f2e1f; }
.pv-cards i { position: absolute; left: 50%; top: 50%; width: 70px; height: 100px; margin: -50px 0 0 -35px; border-radius: 8px; background: #f6f4ee; border: 3px solid #121212; box-shadow: 3px 4px 0 rgba(0, 0, 0, .35); animation: deal 5s var(--spring) infinite; }
.pv-cards i::after { content: ""; position: absolute; inset: 10px; border-radius: 4px; border: 2px dashed #2346ff; }
.pv-cards i:nth-child(1) { --x: -150px; --r: -18deg; animation-delay: 0s; }
.pv-cards i:nth-child(2) { --x: -75px; --r: -9deg; animation-delay: .15s; }
.pv-cards i:nth-child(3) { --x: 0px; --r: 0deg; animation-delay: .3s; }
.pv-cards i:nth-child(4) { --x: 75px; --r: 9deg; animation-delay: .45s; }
.pv-cards i:nth-child(5) { --x: 150px; --r: 18deg; animation-delay: .6s; }
.pv-cards i:nth-child(3)::after { border-color: #e2504f; }
@keyframes deal { 0% { transform: translate(0, -260px) rotate(40deg); opacity: 0; } 20%, 80% { transform: translate(var(--x), 0) rotate(var(--r)); opacity: 1; } 100% { transform: translate(var(--x), 20px) rotate(var(--r)); opacity: 0; } }

/* the big version on /work pages */
.hero-preview { margin: 8px 0 34px; }
.hero-preview .preview { height: clamp(220px, 42vw, 340px); border-radius: 18px; }

@media (prefers-reduced-motion: reduce) {
  .preview *, .preview *::before, .preview *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
  .pv-paper .sheet i { width: var(--to, 100%); }
  .pv-paper .curve path { stroke-dashoffset: 0; }
  .pv-paper .stars { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .pv-cards i { animation: none !important; transform: translate(var(--x), 0) rotate(var(--r)); } }
