Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions apps/web/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,43 @@ html {
:root:not(.dark) .btn-secondary {
border-color: var(--border);
background: rgba(0, 0, 0, 0.04);
}

/* ---------- Premium Animation & Interaction Pass ---------- */

@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(22px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

.animate-fade-in {
animation: fadeInUp 0.75s cubic-bezier(0.16, 1, 0.3, 1) both;
will-change: transform, opacity;
}

.glass {
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.glass:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px -15px rgba(99, 102, 241, 0.15), var(--shadow-nav);
border-color: rgba(99, 102, 241, 0.35);
}

/* Specific section scale-ups on hover */
.kpi-grid > *, .reputation-widgets > *, .velocity-widgets > *, .networking-widgets > *, .match-widgets > *, .event-widgets > *, .ranking-widgets > *, .monetization-widgets > *, .mentor-widgets > *, .team-widgets > *, .web3-widgets > *, .export-widgets > * {
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.kpi-grid > *:hover, .reputation-widgets > *:hover, .velocity-widgets > *:hover, .networking-widgets > *:hover, .match-widgets > *:hover, .event-widgets > *:hover, .ranking-widgets > *:hover, .monetization-widgets > *:hover, .mentor-widgets > *:hover, .team-widgets > *:hover, .web3-widgets > *:hover, .export-widgets > *:hover {
transform: translateY(-3px) scale(1.01);
box-shadow: 0 15px 30px -10px rgba(99, 102, 241, 0.12), var(--shadow-nav);
border-color: rgba(99, 102, 241, 0.3);
}
15 changes: 15 additions & 0 deletions apps/web/src/lib/components/AIEngagementInsights.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import InsightFeed from '$lib/components/InsightFeed.svelte';

let {
insights = [
{ type: 'positive', text: 'Peak engagement detected! You just connected with 5 senior engineers in the last hour.' },
{ type: 'warning', text: 'Your event visibility is dropping. Scan 2 more QR codes to stay on the leaderboard.' },
{ type: 'neutral', text: 'You have a 60% skill overlap with the current hackathon attendees.' }
]
} = $props<{
insights?: { type: 'positive' | 'warning' | 'neutral', text: string }[];
}>();
</script>

<InsightFeed title="Engagement Intelligence" items={insights} variant="ai" />
20 changes: 20 additions & 0 deletions apps/web/src/lib/components/AISkillMatcher.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script lang="ts">
import InsightFeed from '$lib/components/InsightFeed.svelte';

let {
predictions = [
{ type: 'positive', text: 'You are highly compatible with <strong>DevCard API V2</strong> contributors based on your recent Fastify commits.' },
{ type: 'neutral', text: 'Consider joining the <em>Open Source Saturday</em> meetup. 12 matching developers will be there.' },
{ type: 'warning', text: 'Your backend skill overlap is high, but your profile lacks recent database contributions.' }
]
} = $props<{
predictions?: { type: 'positive' | 'warning' | 'neutral', text: string }[];
}>();
</script>

<InsightFeed
title="AI Collaborator Predictions"
items={predictions}
variant="ai"
accentColor="#22c55e"
/>
111 changes: 111 additions & 0 deletions apps/web/src/lib/components/AchievementBadges.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<script lang="ts">
let {
badges = [
{ id: 1, title: 'First PR', icon: 'M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5', locked: false, color: '#3b82f6' },
{ id: 2, title: 'Hackathon Winner', icon: 'M12 15l-8.5-8.5 1.5-1.5L12 12l7-7 1.5 1.5L12 15z', locked: false, color: '#eab308' },
{ id: 3, title: '100 Commits', icon: 'M22 11.08V12a10 10 0 1 1-5.93-9.14', locked: true, color: '#a8a29e' },
{ id: 4, title: 'Diamond Tier', icon: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z', locked: true, color: '#a8a29e' }
]
} = $props<{
badges?: { id: number, title: string, icon: string, locked: boolean, color: string }[];
}>();
</script>

<div class="achievement-badges glass">
<div class="header">
<h3>Achievements</h3>
</div>

<div class="badges-grid">
{#each badges as badge}
<div class="badge-item {badge.locked ? 'locked' : ''}">
<div class="icon-container" style="color: {badge.color}">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d={badge.icon} />
</svg>
</div>
<span class="badge-title">{badge.title}</span>
{#if badge.locked}
<div class="lock-overlay">
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>
</div>
{/if}
</div>
{/each}
</div>
</div>

<style>
.achievement-badges {
padding: 1.5rem;
border-radius: var(--radius-lg);
display: flex;
flex-direction: column;
gap: 1.5rem;
height: 100%;
}

.header h3 {
font-size: 1.125rem;
color: var(--text-primary);
margin: 0;
}

.badges-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
gap: 1rem;
flex: 1;
}

.badge-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 1rem 0.5rem;
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: var(--radius);
position: relative;
transition: transform 0.2s;
}

.badge-item:not(.locked):hover {
transform: translateY(-4px);
border-color: rgba(255, 255, 255, 0.1);
}

.icon-container {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.05);
border-radius: 50%;
padding: 0.75rem;
}

.badge-title {
font-size: 0.75rem;
color: var(--text-secondary);
text-align: center;
font-weight: 500;
}

.locked {
opacity: 0.5;
filter: grayscale(1);
}

.lock-overlay {
position: absolute;
top: 5px;
right: 5px;
color: var(--text-muted);
}
</style>
Loading