Add card components, cards route, xml-bible tests, and progress page update

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
George Powell
2026-04-14 00:00:55 -04:00
parent f7efe6738d
commit 1c2f214963
4 changed files with 273 additions and 2 deletions
+61
View File
@@ -0,0 +1,61 @@
<script lang="ts">
import type { Attachment } from "svelte/attachments";
interface Props {
front: string;
back: string;
}
let { front, back }: Props = $props();
let fanned = $state(false);
const cardDeck: Attachment<HTMLDivElement> = (node) => {
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
fanned = entry.isIntersecting;
}
},
{ rootMargin: "-40% 0px -40% 0px", threshold: 0 }
);
observer.observe(node);
const onEnter = () => (fanned = true);
const onLeave = () => (fanned = false);
node.addEventListener("mouseenter", onEnter);
node.addEventListener("mouseleave", onLeave);
return () => {
observer.disconnect();
node.removeEventListener("mouseenter", onEnter);
node.removeEventListener("mouseleave", onLeave);
};
};
</script>
<div
{@attach cardDeck}
class="relative h-64 w-48 cursor-pointer"
role="img"
aria-label="Card deck"
>
<!-- Back card -->
<img
src={back}
alt="Back"
class="absolute inset-0 max-h-64 w-full object-contain drop-shadow-md transition-all duration-500 ease-in-out"
style:transform={fanned ? "translateX(85px) rotate(5deg)" : "rotate(-2deg)"}
style:z-index="1"
/>
<!-- Front card -->
<img
src={front}
alt="Front"
class="absolute inset-0 max-h-64 w-full object-contain drop-shadow-md transition-all duration-500 ease-in-out"
style:transform={fanned ? "translateX(-85px) rotate(-5deg)" : "rotate(2deg)"}
style:z-index="2"
/>
</div>