feat: add Tier 2 shared components (stats, tags, media)

New shared-ui components:
- GlassCard: Glassmorphism container for cards
- StatRow: Generic stat row with snippet-based icons
- TagBadge: Reusable tag badge component
- AudioPlayer: Full-featured audio player with customizable icons

Updated Memoro to use shared components as wrappers while
maintaining app-specific features (icons, styling).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Till-JS 2025-11-24 22:39:15 +01:00
parent f93cb997cf
commit 10325026f9
13 changed files with 513 additions and 304 deletions

View file

@ -0,0 +1,25 @@
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
/** Content to render inside the card */
children: Snippet;
/** Additional CSS classes */
class?: string;
}
let { children, class: className = '' }: Props = $props();
</script>
<div
class="glass-card relative overflow-hidden rounded-3xl border border-theme bg-black/[0.02] dark:bg-white/[0.02] p-6 shadow-lg {className}"
>
{@render children()}
</div>
<style>
/* Glassmorphism effect */
.glass-card {
backdrop-filter: blur(10px);
}
</style>

View file

@ -0,0 +1,39 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import { Text } from '../../atoms';
interface Props {
/** Title/label for the stat */
title: string;
/** Value to display */
value: string;
/** Optional subtitle/description */
subtitle?: string;
/** Icon snippet - allows custom icon rendering */
icon?: Snippet;
}
let { title, value, subtitle, icon }: Props = $props();
</script>
<div
class="flex items-center gap-3 border border-theme bg-black/[0.03] dark:bg-white/[0.06] px-3 py-2.5 transition-colors hover:bg-black/[0.06] dark:hover:bg-white/[0.12] first:rounded-t-xl last:rounded-b-xl"
>
<!-- Icon slot -->
{#if icon}
<div class="flex-shrink-0 text-theme-secondary">
{@render icon()}
</div>
{/if}
<!-- Content -->
<div class="flex-1">
<Text variant="small" weight="medium">{title}</Text>
{#if subtitle}
<Text variant="muted" class="mt-0.5">{subtitle}</Text>
{/if}
</div>
<!-- Value -->
<Text variant="body" weight="bold" class="text-right">{value}</Text>
</div>

View file

@ -0,0 +1,2 @@
export { default as GlassCard } from './GlassCard.svelte';
export { default as StatRow } from './StatRow.svelte';