-
{title}
-
- {description && t.showDescription && (
-
{description}
- )}
-
-
-
- {creator && (
- <>
-
-
-
- {creator.name.slice(0, 2).toUpperCase()}
-
-
-
{creator.name}
- >
- )}
-
-
- {participantCount.toLocaleString()} participants
-
-
-
-
- Ends {endDate.toLocaleDateString("en-US", { month: "short", day: "numeric" })}
- {totalStake.toLocaleString()} XLM
-
-
-
-
-
- {progressPercent}% funded
- {isEnded ? "Ended" : formatTimeRemaining(timeRemaining)}
-
-
-
-
- );
-}
-
-function formatTimeRemaining(ms: number): string {
- const seconds = Math.floor(ms / 1000);
- const minutes = Math.floor(seconds / 60);
- const hours = Math.floor(minutes / 60);
- const days = Math.floor(hours / 24);
- if (days > 0) return `${days}d left`;
- if (hours > 0) return `${hours}h left`;
- if (minutes > 0) return `${minutes}m left`;
- return `${seconds}s left`;
-}
\ No newline at end of file
diff --git a/docs/touch-ripple.md b/docs/touch-ripple.md
new file mode 100644
index 00000000..4a18e0db
--- /dev/null
+++ b/docs/touch-ripple.md
@@ -0,0 +1,24 @@
+# Touch Ripple Feedback
+
+Prediction cards use the shared `touch-ripple` utility from `app/styles/touch.css`
+for tactile press feedback on mobile and pointer devices.
+
+## Usage
+
+Apply `touch-ripple` together with `touch-target`, `relative`, and
+`overflow-hidden` on the interactive card surface:
+
+```tsx
+