diff --git a/apps/web/package.json b/apps/web/package.json index d1461ec..76c8b39 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -10,12 +10,16 @@ "preview": "vite preview" }, "dependencies": { + "html5-qrcode": "^2.3.8", + "lucide-react": "^0.344.0", + "motion": "^12.4.7", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@babel/core": "^7.29.0", "@eslint/js": "^9.39.4", + "@tailwindcss/vite": "^4.0.0", "@rolldown/plugin-babel": "^0.2.1", "@types/babel__core": "^7.20.5", "@types/node": "^24.12.0", @@ -27,6 +31,7 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react-refresh": "^0.5.2", "globals": "^17.4.0", + "tailwindcss": "^4.0.0", "typescript": "~5.9.3", "typescript-eslint": "^8.57.0", "vite": "^8.0.1" diff --git a/apps/web/public/cosc.png b/apps/web/public/cosc.png new file mode 100644 index 0000000..8bcde57 Binary files /dev/null and b/apps/web/public/cosc.png differ diff --git a/apps/web/public/dk24.png b/apps/web/public/dk24.png new file mode 100644 index 0000000..68b915f Binary files /dev/null and b/apps/web/public/dk24.png differ diff --git a/apps/web/public/favicon.svg b/apps/web/public/favicon.svg deleted file mode 100644 index 6893eb1..0000000 --- a/apps/web/public/favicon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/web/public/icons.svg b/apps/web/public/icons.svg deleted file mode 100644 index e952219..0000000 --- a/apps/web/public/icons.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 46a5992..1f75211 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -1,121 +1,154 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from './assets/vite.svg' -import heroImg from './assets/hero.png' -import './App.css' +/** + * @license + * SPDX-License-Identifier: Apache-2.0 + */ -function App() { - const [count, setCount] = useState(0) +import { useState, useEffect } from "react"; +import LoginScreen from "./components/LoginScreen"; +import RatingScreen from "./components/RatingScreen"; +import ProgressScreen from "./components/ProgressScreen"; +import ScannerScreen from "./components/ScannerScreen"; +import CompletionScreen from "./components/CompletionScreen"; + +type Screen = 'login' | 'rating' | 'progress' | 'scanner' | 'completion'; + +export default function App() { + const [currentScreen, setCurrentScreen] = useState('login'); + const [isLoggedIn, setIsLoggedIn] = useState(() => localStorage.getItem('isLoggedIn') === 'true'); + const [unlockedStalls, setUnlockedStalls] = useState(() => { + const saved = localStorage.getItem('unlockedStalls'); + return saved ? JSON.parse(saved) : []; + }); + const [ratings, setRatings] = useState>(() => { + const saved = localStorage.getItem('ratings'); + return saved ? JSON.parse(saved) : {}; + }); + const [currentStallId, setCurrentStallId] = useState(null); + + const totalStalls = 5; + + // Handle URL parameter on mount + useEffect(() => { + const params = new URLSearchParams(window.location.search); + const stallId = params.get('stallId'); + + if (stallId) { + setCurrentStallId(stallId); + // If not logged in, we stay on login but remember the stallId + if (isLoggedIn) { + // If logged in and stall is already rated, go to progress + if (ratings[stallId] !== undefined) { + setCurrentScreen('progress'); + } else { + // Unlock it and go to rating + unlockStall(stallId); + setCurrentScreen('rating'); + } + } else { + setCurrentScreen('login'); + } + // Clean up URL + window.history.replaceState({}, document.title, window.location.pathname); + } else if (isLoggedIn) { + setCurrentScreen('progress'); + } + }, []); + + const unlockStall = (id: string) => { + setUnlockedStalls(prev => { + if (prev.includes(id)) return prev; + const next = [...prev, id]; + localStorage.setItem('unlockedStalls', JSON.stringify(next)); + return next; + }); + }; + + const handleLogin = () => { + setIsLoggedIn(true); + localStorage.setItem('isLoggedIn', 'true'); + + if (currentStallId) { + unlockStall(currentStallId); + setCurrentScreen('rating'); + } else { + setCurrentScreen('progress'); + } + }; + + const handleRatingSubmit = (rating: number) => { + if (!currentStallId) return; + + const newRatings = { ...ratings, [currentStallId]: rating }; + setRatings(newRatings); + localStorage.setItem('ratings', JSON.stringify(newRatings)); + + const ratedCount = Object.keys(newRatings).length; + if (ratedCount >= totalStalls) { + setCurrentScreen('completion'); + } else { + setCurrentScreen('progress'); + } + }; + + const handleScanSuccess = (decodedText: string) => { + // Expecting URL like https://.../?stallId=5 or just "5" + let stallId = decodedText; + try { + if (decodedText.includes('stallId=')) { + const url = new URL(decodedText); + stallId = url.searchParams.get('stallId') || decodedText; + } + } catch (e) { + // Not a URL, use as is + } + + setCurrentStallId(stallId); + unlockStall(stallId); + setCurrentScreen('rating'); + }; return ( - <> -
-
- - React logo - Vite logo -
-
-

Get started

-

- Edit src/App.tsx and save to test HMR -

-
- -
- -
- -
-
- -

Documentation

-

Your questions, answered

- -
-
- -

Connect with us

-

Join the Vite community

- -
-
- -
-
- - ) +
+ {currentScreen === 'login' && ( + + )} + + {currentScreen === 'scanner' && ( + setCurrentScreen('progress')} + /> + )} + + {currentScreen === 'rating' && currentStallId && ( + setCurrentScreen('scanner')} + onProgress={() => setCurrentScreen('progress')} + onSubmitSuccess={handleRatingSubmit} + ratedCount={Object.keys(ratings).length} + totalCount={totalStalls} + /> + )} + + {currentScreen === 'progress' && ( + setCurrentScreen('scanner')} + totalCount={totalStalls} + onBackToVote={() => setCurrentScreen('scanner')} + /> + )} + + {currentScreen === 'completion' && ( + setCurrentScreen('progress')} + onGoToProfile={() => setCurrentScreen('progress')} + onViewLeaderboard={() => setCurrentScreen('progress')} + /> + )} +
+ ); } -export default App diff --git a/apps/web/src/components/CompletionScreen.tsx b/apps/web/src/components/CompletionScreen.tsx new file mode 100644 index 0000000..3373d5b --- /dev/null +++ b/apps/web/src/components/CompletionScreen.tsx @@ -0,0 +1,77 @@ +import { motion } from 'motion/react'; +import { X, CheckCircle2, Star } from 'lucide-react'; + +interface CompletionScreenProps { + onClose: () => void; + onGoToProfile: () => void; + onViewLeaderboard: () => void; +} + +export default function CompletionScreen({ onClose }: CompletionScreenProps) { + return ( +
+ {/* Header */} +
+

Coastal Startup Fest

+ +
+ +
+ {/* Hero Illustration */} +
+ {/* Background Decorative Frame */} +
+
+ + {/* Main Visual (Red/Orange Card) */} + +
+
+ +
+ + + {/* Submission Success Card Overlay */} + +
+ +
+
+ Submission Success +
+ 15/15 +
+ Stalls Rated Today +
+
+
+ + {/* Text Content */} +
+

+ You've rated all
+ 15 stalls! +

+

+ Your votes are now officially counted.
+ Thank you for participating! +

+
+
+
+ ); +} diff --git a/apps/web/src/components/LoginScreen.tsx b/apps/web/src/components/LoginScreen.tsx new file mode 100644 index 0000000..74fe54d --- /dev/null +++ b/apps/web/src/components/LoginScreen.tsx @@ -0,0 +1,113 @@ +import { motion } from "motion/react"; + +interface LoginScreenProps { + onStart?: () => void; +} + +export default function LoginScreen({ onStart }: LoginScreenProps) { + return ( +
+ {/* Background Patterns */} +
+ {/* Subtle Dot Grid */} +
+ + {/* Topographic Background Lines */} + + + + + + + + +
+ +
+
+ {/* Logo Section */} + +
+ {/* Logo Placeholder */} +
+ LOGO +
+

+ Coastal
Startup Fest +

+
+
+ + {/* Tagline */} + + Empowering the next generation of coastal entrepreneurs! + +
+ + {/* Action Section */} +
+ + Get Started + + + {/* Powered By Section */} + +
+ Powered by +
+
+ DK24 +
+ DK24 +
+
+ + {/* Additional Logos Section */} +
+ {[ + { id: 1, src: '/cosc.png', alt: 'COSC' }, + { id: 2, src: null, alt: 'LOGO 2' }, + { id: 3, src: null, alt: 'LOGO 3' } + ].map((logo) => ( +
+
+ {logo.src ? ( + {logo.alt} + ) : ( + {logo.alt} + )} +
+
+ ))} +
+
+
+ + {/* Home Indicator (Hidden on Desktop) */} +
+
+
+ ); +} + + diff --git a/apps/web/src/components/ProgressScreen.tsx b/apps/web/src/components/ProgressScreen.tsx new file mode 100644 index 0000000..bc833ae --- /dev/null +++ b/apps/web/src/components/ProgressScreen.tsx @@ -0,0 +1,192 @@ +import { motion } from 'motion/react'; +import { UserCircle, QrCode, CheckCircle2, Lock, Vote, BarChart3, User, ChevronLeft } from 'lucide-react'; + +interface ProgressScreenProps { + onBackToVote?: () => void; + onProfile?: () => void; + onScanNext?: () => void; + unlockedStalls?: string[]; + ratings?: Record; + totalCount?: number; +} + +export default function ProgressScreen({ + onBackToVote, + onProfile, + onScanNext, + unlockedStalls = [], + ratings = {}, + totalCount = 5 +}: ProgressScreenProps) { + const ratedCount = Object.keys(ratings).length; + const progressPercentage = Math.round((ratedCount / totalCount) * 100); + + return ( +
+ {/* Header */} +
+
+ +

Coastal Startup Fest

+
+
+ +
+
+ +
+ {/* Hero Section */} +
+ Your Journey +

You're making progress!

+ + {/* Progress Summary Card */} + +
+
+
+ {ratedCount} + /{totalCount} +
+ Stalls Rated +
+
+ {progressPercentage}% Complete +
+
+
+ +
+
+ + {/* Scan Button / Completion Action */} + {ratedCount < totalCount ? ( + + + Scan the next QR code + + ) : ( + + + All Stalls Rated! + + )} +
+ + {/* Directory Section */} +
+
+

Stall Directory

+
+ +
+ {Array.from({ length: totalCount }).map((_, i) => { + const stallNumber = i + 1; + const stallId = stallNumber.toString(); + const isUnlocked = unlockedStalls.includes(stallId); + const isRated = ratings[stallId] !== undefined; + + const status = isRated ? 'rated' : (isUnlocked ? 'pending' : 'locked'); + const displayId = String(stallNumber).padStart(2, '0'); + + return ( + +
+
+ {displayId} +
+
+

+ {status === 'locked' ? 'Locked Stall' : `Eco-Tech Stall #${displayId}`} +

+ + {isRated ? 'Rating submitted' : status === 'pending' ? 'Ready to rate' : 'Scan QR to unlock'} + +
+
+ +
+ {status === 'rated' && ( +
+ +
+ )} + {status === 'pending' && ( +
+ +
+ )} + {status === 'locked' && ( +
+ +
+ )} +
+
+ ); + })} +
+
+
+ + {/* Bottom Navigation */} + +
+ ); +} diff --git a/apps/web/src/components/RatingScreen.tsx b/apps/web/src/components/RatingScreen.tsx new file mode 100644 index 0000000..2468710 --- /dev/null +++ b/apps/web/src/components/RatingScreen.tsx @@ -0,0 +1,182 @@ +import { useState } from 'react'; +import { motion } from 'motion/react'; +import { User, ChevronLeft, Send, BarChart3, UserCircle, Vote } from 'lucide-react'; + +interface RatingScreenProps { + stallId: string; + onBack?: () => void; + onProgress?: () => void; + onSubmitSuccess?: (rating: number) => void; + ratedCount?: number; + totalCount?: number; +} + +export default function RatingScreen({ stallId, onBack, onProgress, onSubmitSuccess, ratedCount = 0, totalCount = 5 }: RatingScreenProps) { + const [selectedRating, setSelectedRating] = useState(null); + const [isSubmitted, setIsSubmitted] = useState(false); + + const handleSubmit = () => { + if (selectedRating !== null) { + setIsSubmitted(true); + + // Simulate network delay then redirect + setTimeout(() => { + onSubmitSuccess?.(selectedRating); + }, 1500); + } + }; + + const ratings = Array.from({ length: 11 }, (_, i) => i); + + return ( +
+ {/* Header */} +
+
+ +

Coastal Startup Fest

+
+
+ +
+
+ +
+ {/* Progress Section */} +
+
+
+ Your Progress +

{ratedCount}/{totalCount} stalls rated

+
+ {Math.round((ratedCount / totalCount) * 100)}% +
+
+ +
+
+ + {/* Current Stall Card */} +
+ + {/* Topographic Pattern Overlay */} + + + + + + +
+
+
+ +
+
+ Current Stall +

Stall #{stallId.padStart(2, '0')}: Eco-Tech Solutions

+

+ Innovating sustainable hardware for the next digital era. +

+
+
+
+ + {/* Rating Grid */} +
+
+

+ {isSubmitted ? 'Your rating has been recorded' : 'Rate this stall from 0 to 10'} +

+

+ {isSubmitted ? `You voted ${selectedRating}/10 for this stall` : 'Tap a number to cast your vote'} +

+
+ +
+ {ratings.map((rating) => ( + setSelectedRating(rating)} + className={` + aspect-square rounded-2xl flex items-center justify-center text-xl font-bold transition-all border-2 + ${selectedRating === rating + ? 'bg-[#FF2D55] border-[#FF2D55] text-white shadow-lg shadow-red-500/30' + : 'bg-slate-50 border-slate-100 text-slate-400 hover:border-slate-200'} + ${isSubmitted && selectedRating !== rating ? 'opacity-40' : ''} + ${isSubmitted ? 'cursor-default' : ''} + `} + > + {rating} + + ))} +
+
+ + {/* Submit Button */} +
+ + {isSubmitted ? 'Vote Recorded' : 'Submit Rating'} + {!isSubmitted && } + {isSubmitted && ( + +
+ + )} + +
+
+ + {/* Bottom Navigation */} + +
+ ); +} diff --git a/apps/web/src/components/ScannerScreen.tsx b/apps/web/src/components/ScannerScreen.tsx new file mode 100644 index 0000000..dbd9c0a --- /dev/null +++ b/apps/web/src/components/ScannerScreen.tsx @@ -0,0 +1,162 @@ +import { useState, useEffect, useRef } from 'react'; +import { motion } from 'motion/react'; +import { QrCode, X, Zap, Image as ImageIcon, ChevronLeft } from 'lucide-react'; +import { Html5Qrcode } from 'html5-qrcode'; + +interface ScannerScreenProps { + onScanSuccess: (decodedText: string) => void; + onClose: () => void; +} + +export default function ScannerScreen({ onScanSuccess, onClose }: ScannerScreenProps) { + const [isScanning, setIsScanning] = useState(true); + const [error, setError] = useState(null); + const scannerRef = useRef(null); + + useEffect(() => { + const scanner = new Html5Qrcode("reader"); + scannerRef.current = scanner; + + const startScanner = async () => { + try { + await scanner.start( + { facingMode: "environment" }, + { + fps: 10, + qrbox: { width: 250, height: 250 }, + }, + (decodedText: string) => { + // Success + setIsScanning(false); + scanner.stop().then(() => { + onScanSuccess(decodedText); + }).catch((err: unknown) => { + console.error("Failed to stop scanner", err); + onScanSuccess(decodedText); // Still proceed + }); + }, + () => { + // parse error, ignore it. + } + ); + } catch (err) { + console.error("Unable to start scanning", err); + setError("Camera access denied or not available. Please ensure you have granted camera permissions."); + } + }; + + startScanner(); + + return () => { + if (scannerRef.current && scannerRef.current.isScanning) { + scannerRef.current.stop().catch((err: unknown) => console.error("Cleanup stop failed", err)); + } + }; + }, [onScanSuccess]); + + return ( +
+ {/* Header */} +
+ +
+ + Auto Flash +
+ +
+ + {/* Scanner Viewfinder */} +
+ {/* Camera Feed Container */} +
+ {error && ( +
+
+ +

{error}

+ +
+
+ )} +
+ + {/* Scanning Area Overlay */} +
+ {/* Corners */} +
+
+
+
+ + {/* Scanning Line */} + {isScanning && !error && ( + + )} + + {/* QR Code Placeholder (only if not scanning yet or error) */} + {!error && isScanning && ( +
+ +
+ )} +
+ +
+

Scan Stall QR Code

+

Align the QR code within the frame to start rating the stall.

+
+
+ + {/* Footer Actions */} +
+ + + +
+ + {/* Success Overlay */} + {!isScanning && !error && ( + + +
+ +
+

Stall Identified!

+

Redirecting to rating page...

+
+
+ )} +
+ ); +} diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 5fb3313..3b56f0c 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1,111 +1,26 @@ -:root { - --text: #6b6375; - --text-h: #08060d; - --bg: #fff; - --border: #e5e4e7; - --code-bg: #f4f3ec; - --accent: #aa3bff; - --accent-bg: rgba(170, 59, 255, 0.1); - --accent-border: rgba(170, 59, 255, 0.5); - --social-bg: rgba(244, 243, 236, 0.5); - --shadow: - rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Outfit:wght@400;600;700&display=swap'); +@import "tailwindcss"; - --sans: system-ui, 'Segoe UI', Roboto, sans-serif; - --heading: system-ui, 'Segoe UI', Roboto, sans-serif; - --mono: ui-monospace, Consolas, monospace; - - font: 18px/145% var(--sans); - letter-spacing: 0.18px; - color-scheme: light dark; - color: var(--text); - background: var(--bg); - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - @media (max-width: 1024px) { - font-size: 16px; - } +@theme { + --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; + --font-display: "Outfit", sans-serif; + + --color-brand-orange: #FF6B4A; + --color-brand-red: #FF4141; } -@media (prefers-color-scheme: dark) { - :root { - --text: #9ca3af; - --text-h: #f3f4f6; - --bg: #16171d; - --border: #2e303a; - --code-bg: #1f2028; - --accent: #c084fc; - --accent-bg: rgba(192, 132, 252, 0.15); - --accent-border: rgba(192, 132, 252, 0.5); - --social-bg: rgba(47, 48, 58, 0.5); - --shadow: - rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px; - } - - #social .button-icon { - filter: invert(1) brightness(2); +@layer base { + body { + @apply font-sans antialiased text-white overflow-hidden; } } -#root { - width: 1126px; - max-width: 100%; - margin: 0 auto; - text-align: center; - border-inline: 1px solid var(--border); - min-height: 100svh; - display: flex; - flex-direction: column; - box-sizing: border-box; -} - -body { - margin: 0; -} - -h1, -h2 { - font-family: var(--heading); - font-weight: 500; - color: var(--text-h); -} - -h1 { - font-size: 56px; - letter-spacing: -1.68px; - margin: 32px 0; - @media (max-width: 1024px) { - font-size: 36px; - margin: 20px 0; - } -} -h2 { - font-size: 24px; - line-height: 118%; - letter-spacing: -0.24px; - margin: 0 0 8px; - @media (max-width: 1024px) { - font-size: 20px; - } -} -p { - margin: 0; -} - -code, -.counter { - font-family: var(--mono); - display: inline-flex; - border-radius: 4px; - color: var(--text-h); +.bg-wevote-gradient { + background: linear-gradient(180deg, #FF7E5F 0%, #FF2D55 100%); } -code { - font-size: 15px; - line-height: 135%; - padding: 4px 8px; - background: var(--code-bg); +.topographic-line { + fill: none; + stroke: rgba(255, 255, 255, 0.4); + stroke-width: 2; } diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index d1203cd..ff58f50 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -1,11 +1,14 @@ import { defineConfig } from 'vite' import react, { reactCompilerPreset } from '@vitejs/plugin-react' import babel from '@rolldown/plugin-babel' +import tailwindcss from '@tailwindcss/vite' // https://vite.dev/config/ export default defineConfig({ plugins: [ + tailwindcss(), react(), babel({ presets: [reactCompilerPreset()] }) ], }) +// trigger vite reload diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9209090 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,115 @@ +{ + "name": "voting-system", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "voting-system", + "devDependencies": { + "turbo": "latest" + } + }, + "node_modules/@turbo/darwin-64": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/@turbo/darwin-64/-/darwin-64-2.8.20.tgz", + "integrity": "sha512-FQ9EX1xMU5nbwjxXxM3yU88AQQ6Sqc6S44exPRroMcx9XZHqqppl5ymJF0Ig/z3nvQNwDmz1Gsnvxubo+nXWjQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@turbo/darwin-arm64": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/@turbo/darwin-arm64/-/darwin-arm64-2.8.20.tgz", + "integrity": "sha512-Gpyh9ATFGThD6/s9L95YWY54cizg/VRWl2B67h0yofG8BpHf67DFAh9nuJVKG7bY0+SBJDAo5cMur+wOl9YOYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@turbo/linux-64": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/@turbo/linux-64/-/linux-64-2.8.20.tgz", + "integrity": "sha512-p2QxWUYyYUgUFG0b0kR+pPi8t7c9uaVlRtjTTI1AbCvVqkpjUfCcReBn6DgG/Hu8xrWdKLuyQFaLYFzQskZbcA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@turbo/linux-arm64": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/@turbo/linux-arm64/-/linux-arm64-2.8.20.tgz", + "integrity": "sha512-Gn5yjlZGLRZWarLWqdQzv0wMqyBNIdq1QLi48F1oY5Lo9kiohuf7BPQWtWxeNVS2NgJ1+nb/DzK1JduYC4AWOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@turbo/windows-64": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/@turbo/windows-64/-/windows-64-2.8.20.tgz", + "integrity": "sha512-vyaDpYk/8T6Qz5V/X+ihKvKFEZFUoC0oxYpC1sZanK6gaESJlmV3cMRT3Qhcg4D2VxvtC2Jjs9IRkrZGL+exLw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@turbo/windows-arm64": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/@turbo/windows-arm64/-/windows-arm64-2.8.20.tgz", + "integrity": "sha512-voicVULvUV5yaGXo0Iue13BcHGYW3u0VgqSbfQwBaHbpj1zLjYV4KIe+7fYIo6DO8FVUJzxFps3ODCQG/Wy2Qw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/turbo": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/turbo/-/turbo-2.8.20.tgz", + "integrity": "sha512-Rb4qk5YT8RUwwdXtkLpkVhNEe/lor6+WV7S5tTlLpxSz6MjV5Qi8jGNn4gS6NAvrYGA/rNrE6YUQM85sCZUDbQ==", + "dev": true, + "license": "MIT", + "bin": { + "turbo": "bin/turbo" + }, + "optionalDependencies": { + "@turbo/darwin-64": "2.8.20", + "@turbo/darwin-arm64": "2.8.20", + "@turbo/linux-64": "2.8.20", + "@turbo/linux-arm64": "2.8.20", + "@turbo/windows-64": "2.8.20", + "@turbo/windows-arm64": "2.8.20" + } + } + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e2a4b8..cc588b8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,15 @@ importers: apps/web: dependencies: + html5-qrcode: + specifier: ^2.3.8 + version: 2.3.8 + lucide-react: + specifier: ^0.344.0 + version: 0.344.0(react@19.2.4) + motion: + specifier: ^12.4.7 + version: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: specifier: ^19.2.4 version: 19.2.4 @@ -60,7 +69,10 @@ importers: version: 9.39.4 '@rolldown/plugin-babel': specifier: ^0.2.1 - version: 0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.10)(vite@8.0.1(@types/node@24.12.0)) + version: 0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.11)(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1)) + '@tailwindcss/vite': + specifier: ^4.0.0 + version: 4.2.2(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1)) '@types/babel__core': specifier: ^7.20.5 version: 7.20.5 @@ -75,31 +87,34 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: ^6.0.1 - version: 6.0.1(@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.10)(vite@8.0.1(@types/node@24.12.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.1(@types/node@24.12.0)) + version: 6.0.1(@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.11)(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1)) babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 eslint: specifier: ^9.39.4 - version: 9.39.4 + version: 9.39.4(jiti@2.6.1) eslint-plugin-react-hooks: specifier: ^7.0.1 - version: 7.0.1(eslint@9.39.4) + version: 7.0.1(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-refresh: specifier: ^0.5.2 - version: 0.5.2(eslint@9.39.4) + version: 0.5.2(eslint@9.39.4(jiti@2.6.1)) globals: specifier: ^17.4.0 version: 17.4.0 + tailwindcss: + specifier: ^4.0.0 + version: 4.2.2 typescript: specifier: ~5.9.3 version: 5.9.3 typescript-eslint: specifier: ^8.57.0 - version: 8.57.1(eslint@9.39.4)(typescript@5.9.3) + version: 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) vite: specifier: ^8.0.1 - version: 8.0.1(@types/node@24.12.0) + version: 8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1) packages/shared: devDependencies: @@ -907,36 +922,69 @@ packages: '@oxc-project/types@0.120.0': resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==} + '@oxc-project/types@0.122.0': + resolution: {integrity: sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==} + '@rolldown/binding-android-arm64@1.0.0-rc.10': resolution: {integrity: sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.0.0-rc.11': + resolution: {integrity: sha512-SJ+/g+xNnOh6NqYxD0V3uVN4W3VfnrGsC9/hoglicgTNfABFG9JjISvkkU0dNY84MNHLWyOgxP9v9Y9pX4S7+A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.0.0-rc.10': resolution: {integrity: sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.0.0-rc.11': + resolution: {integrity: sha512-7WQgR8SfOPwmDZGFkThUvsmd/nwAWv91oCO4I5LS7RKrssPZmOt7jONN0cW17ydGC1n/+puol1IpoieKqQidmg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-rc.10': resolution: {integrity: sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.0.0-rc.11': + resolution: {integrity: sha512-39Ks6UvIHq4rEogIfQBoBRusj0Q0nPVWIvqmwBLaT6aqQGIakHdESBVOPRRLacy4WwUPIx4ZKzfZ9PMW+IeyUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.0.0-rc.10': resolution: {integrity: sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.0.0-rc.11': + resolution: {integrity: sha512-jfsm0ZHfhiqrvWjJAmzsqiIFPz5e7mAoCOPBNTcNgkiid/LaFKiq92+0ojH+nmJmKYkre4t71BWXUZDNp7vsag==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': resolution: {integrity: sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.11': + resolution: {integrity: sha512-zjQaUtSyq1nVe3nxmlSCuR96T1LPlpvmJ0SZy0WJFEsV4kFbXcq2u68L4E6O0XeFj4aex9bEauqjW8UQBeAvfQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': resolution: {integrity: sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -944,6 +992,12 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.11': + resolution: {integrity: sha512-WMW1yE6IOnehTcFE9eipFkm3XN63zypWlrJQ2iF7NrQ9b2LDRjumFoOGJE8RJJTJCTBAdmLMnJ8uVitACUUo1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': resolution: {integrity: sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==} engines: {node: ^20.19.0 || >=22.12.0} @@ -951,6 +1005,12 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.11': + resolution: {integrity: sha512-jfndI9tsfm4APzjNt6QdBkYwre5lRPUgHeDHoI7ydKUuJvz3lZeCfMsI56BZj+7BYqiKsJm7cfd/6KYV7ubrBg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': resolution: {integrity: sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -958,6 +1018,12 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.11': + resolution: {integrity: sha512-ZlFgw46NOAGMgcdvdYwAGu2Q+SLFA9LzbJLW+iyMOJyhj5wk6P3KEE9Gct4xWwSzFoPI7JCdYmYMzVtlgQ+zfw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': resolution: {integrity: sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -965,6 +1031,12 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.11': + resolution: {integrity: sha512-hIOYmuT6ofM4K04XAZd3OzMySEO4K0/nc9+jmNcxNAxRi6c5UWpqfw3KMFV4MVFWL+jQsSh+bGw2VqmaPMTLyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': resolution: {integrity: sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -972,6 +1044,12 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.11': + resolution: {integrity: sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': resolution: {integrity: sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -979,29 +1057,58 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-x64-musl@1.0.0-rc.11': + resolution: {integrity: sha512-/tpFfoSTzUkH9LPY+cYbqZBDyyX62w5fICq9qzsHLL8uTI6BHip3Q9Uzft0wylk/i8OOwKik8OxW+QAhDmzwmg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': resolution: {integrity: sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.0.0-rc.11': + resolution: {integrity: sha512-mcp3Rio2w72IvdZG0oQ4bM2c2oumtwHfUfKncUM6zGgz0KgPz4YmDPQfnXEiY5t3+KD/i8HG2rOB/LxdmieK2g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': resolution: {integrity: sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==} engines: {node: '>=14.0.0'} cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.0.0-rc.11': + resolution: {integrity: sha512-LXk5Hii1Ph9asuGRjBuz8TUxdc1lWzB7nyfdoRgI0WGPZKmCxvlKk8KfYysqtr4MfGElu/f/pEQRh8fcEgkrWw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': resolution: {integrity: sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.11': + resolution: {integrity: sha512-dDwf5otnx0XgRY1yqxOC4ITizcdzS/8cQ3goOWv3jFAo4F+xQYni+hnMuO6+LssHHdJW7+OCVL3CoU4ycnh35Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': resolution: {integrity: sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.11': + resolution: {integrity: sha512-LN4/skhSggybX71ews7dAj6r2geaMJfm3kMbK2KhFMg9B10AZXnKoLCVVgzhMHL0S+aKtr4p8QbAW8k+w95bAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/plugin-babel@0.2.2': resolution: {integrity: sha512-q9pE8+47bQNHb5eWVcE6oXppA+JTSwvnrhH53m0ZuHuK5MLvwsLoWrWzBTFQqQ06BVxz1gp0HblLsch8o6pvZw==} engines: {node: '>=22.12.0 || ^24.0.0'} @@ -1022,12 +1129,105 @@ packages: '@rolldown/pluginutils@1.0.0-rc.10': resolution: {integrity: sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==} + '@rolldown/pluginutils@1.0.0-rc.11': + resolution: {integrity: sha512-xQO9vbwBecJRv9EUcQ/y0dzSTJgA7Q6UVN7xp6B81+tBGSLVAK03yJ9NkJaUA7JFD91kbjxRSC/mDnmvXzbHoQ==} + '@rolldown/pluginutils@1.0.0-rc.7': resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} '@stablelib/base64@1.0.1': resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} + '@tailwindcss/node@4.2.2': + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + + '@tailwindcss/oxide-android-arm64@4.2.2': + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.2': + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.2': + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + + '@tailwindcss/vite@4.2.2': + resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + '@turbo/darwin-64@2.8.20': resolution: {integrity: sha512-FQ9EX1xMU5nbwjxXxM3yU88AQQ6Sqc6S44exPRroMcx9XZHqqppl5ymJF0Ig/z3nvQNwDmz1Gsnvxubo+nXWjQ==} cpu: [x64] @@ -1426,6 +1626,10 @@ packages: electron-to-chromium@1.5.321: resolution: {integrity: sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==} + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + env-paths@3.0.0: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1585,6 +1789,20 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + framer-motion@12.38.0: + resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1623,6 +1841,9 @@ packages: resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} engines: {node: '>=18'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + hanji@0.0.5: resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==} @@ -1643,6 +1864,9 @@ packages: resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} engines: {node: '>=16.9.0'} + html5-qrcode@2.3.8: + resolution: {integrity: sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1687,6 +1911,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + js-cookie@3.0.5: resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} engines: {node: '>=14'} @@ -1821,9 +2049,17 @@ packages: lru-queue@0.1.0: resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + lucide-react@0.344.0: + resolution: {integrity: sha512-6YyBnn91GB45VuVT96bYCOKElbJzUHqp65vX8cDcu55MQL9T969v4dhGClpljamuI/+KMO9P6w9Acq1CVQGvIQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 + magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + map-obj@4.3.0: resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} engines: {node: '>=8'} @@ -1857,6 +2093,26 @@ packages: resolution: {integrity: sha512-Brg/fp/iAVDOQoHxkuN5bEYhyQlZhxddI78yWsCbeEwTHXQjlNLtiJDUsp1GIptVqMI7/gkJMz4vVAc01mpoBw==} engines: {node: '>=10'} + motion-dom@12.38.0: + resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==} + + motion-utils@12.36.0: + resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==} + + motion@12.38.0: + resolution: {integrity: sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1960,6 +2216,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.0.0-rc.11: + resolution: {integrity: sha512-NRjoKMusSjfRbSYiH3VSumlkgFe7kYAa3pzVOsVYVFY3zb5d7nS+a3KGQ7hJKXuYWbzJKPVQ9Wxq2UvyK+ENpw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup-plugin-inject@3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -2052,6 +2313,13 @@ packages: peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + engines: {node: '>=6'} + timers-ext@0.1.8: resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} engines: {node: '>=0.12'} @@ -2647,9 +2915,9 @@ snapshots: '@esbuild/win32-x64@0.19.12': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -2832,67 +3100,186 @@ snapshots: '@oxc-project/types@0.120.0': {} + '@oxc-project/types@0.122.0': {} + '@rolldown/binding-android-arm64@1.0.0-rc.10': optional: true + '@rolldown/binding-android-arm64@1.0.0-rc.11': + optional: true + '@rolldown/binding-darwin-arm64@1.0.0-rc.10': optional: true + '@rolldown/binding-darwin-arm64@1.0.0-rc.11': + optional: true + '@rolldown/binding-darwin-x64@1.0.0-rc.10': optional: true + '@rolldown/binding-darwin-x64@1.0.0-rc.11': + optional: true + '@rolldown/binding-freebsd-x64@1.0.0-rc.10': optional: true + '@rolldown/binding-freebsd-x64@1.0.0-rc.11': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.11': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': optional: true + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.11': + optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': optional: true + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.11': + optional: true + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.11': + optional: true + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': optional: true + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.11': + optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': optional: true + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.11': + optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': optional: true + '@rolldown/binding-linux-x64-musl@1.0.0-rc.11': + optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': optional: true + '@rolldown/binding-openharmony-arm64@1.0.0-rc.11': + optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true + '@rolldown/binding-wasm32-wasi@1.0.0-rc.11': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.11': + optional: true + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': optional: true - '@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.10)(vite@8.0.1(@types/node@24.12.0))': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.11': + optional: true + + '@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.11)(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1))': dependencies: '@babel/core': 7.29.0 picomatch: 4.0.3 - rolldown: 1.0.0-rc.10 + rolldown: 1.0.0-rc.11 optionalDependencies: - vite: 8.0.1(@types/node@24.12.0) + vite: 8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1) '@rolldown/pluginutils@1.0.0-rc.10': {} + '@rolldown/pluginutils@1.0.0-rc.11': {} + '@rolldown/pluginutils@1.0.0-rc.7': {} '@stablelib/base64@1.0.1': {} + '@tailwindcss/node@4.2.2': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 + + '@tailwindcss/oxide-android-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide@4.2.2': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-x64': 4.2.2 + '@tailwindcss/oxide-freebsd-x64': 4.2.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-x64-musl': 4.2.2 + '@tailwindcss/oxide-wasm32-wasi': 4.2.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + + '@tailwindcss/vite@4.2.2(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1))': + dependencies: + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + tailwindcss: 4.2.2 + vite: 8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1) + '@turbo/darwin-64@2.8.20': optional: true @@ -2953,15 +3340,15 @@ snapshots: dependencies: csstype: 3.2.3 - '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.1 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@5.9.3) @@ -2969,14 +3356,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.1(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.57.1 '@typescript-eslint/types': 8.57.1 '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -2999,13 +3386,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.1(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.57.1 '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -3028,13 +3415,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.1(eslint@9.39.4)(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.57.1 '@typescript-eslint/types': 8.57.1 '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -3044,12 +3431,12 @@ snapshots: '@typescript-eslint/types': 8.57.1 eslint-visitor-keys: 5.0.1 - '@vitejs/plugin-react@6.0.1(@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.10)(vite@8.0.1(@types/node@24.12.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.1(@types/node@24.12.0))': + '@vitejs/plugin-react@6.0.1(@rolldown/plugin-babel@0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.11)(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.1(@types/node@24.12.0) + vite: 8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1) optionalDependencies: - '@rolldown/plugin-babel': 0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.10)(vite@8.0.1(@types/node@24.12.0)) + '@rolldown/plugin-babel': 0.2.2(@babel/core@7.29.0)(rolldown@1.0.0-rc.11)(vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1)) babel-plugin-react-compiler: 1.0.0 acorn-jsx@5.3.2(acorn@8.16.0): @@ -3239,6 +3626,11 @@ snapshots: electron-to-chromium@1.5.321: {} + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.2 + env-paths@3.0.0: {} es5-ext@0.10.64: @@ -3353,20 +3745,20 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-plugin-react-hooks@7.0.1(eslint@9.39.4): + eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.2 - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) hermes-parser: 0.25.1 zod: 4.3.6 zod-validation-error: 4.0.2(zod@4.3.6) transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.5.2(eslint@9.39.4): + eslint-plugin-react-refresh@0.5.2(eslint@9.39.4(jiti@2.6.1)): dependencies: - eslint: 9.39.4 + eslint: 9.39.4(jiti@2.6.1) eslint-scope@8.4.0: dependencies: @@ -3379,9 +3771,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.4: + eslint@9.39.4(jiti@2.6.1): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 @@ -3415,6 +3807,8 @@ snapshots: minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 transitivePeerDependencies: - supports-color @@ -3486,6 +3880,15 @@ snapshots: flatted@3.4.2: {} + framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + motion-dom: 12.38.0 + motion-utils: 12.36.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -3520,6 +3923,8 @@ snapshots: globals@17.4.0: {} + graceful-fs@4.2.11: {} + hanji@0.0.5: dependencies: lodash.throttle: 4.1.1 @@ -3537,6 +3942,8 @@ snapshots: hono@4.12.8: {} + html5-qrcode@2.3.8: {} + ignore@5.3.2: {} ignore@7.0.5: {} @@ -3570,6 +3977,8 @@ snapshots: isexe@2.0.0: {} + jiti@2.6.1: {} + js-cookie@3.0.5: {} js-tokens@4.0.0: {} @@ -3672,10 +4081,18 @@ snapshots: dependencies: es5-ext: 0.10.64 + lucide-react@0.344.0(react@19.2.4): + dependencies: + react: 19.2.4 + magic-string@0.25.9: dependencies: sourcemap-codec: 1.4.8 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + map-obj@4.3.0: {} memoizee@0.4.17: @@ -3724,6 +4141,20 @@ snapshots: dependencies: brace-expansion: 2.0.2 + motion-dom@12.38.0: + dependencies: + motion-utils: 12.36.0 + + motion-utils@12.36.0: {} + + motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + framer-motion: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + ms@2.1.3: {} mustache@4.2.0: {} @@ -3824,6 +4255,27 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.10 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.10 + rolldown@1.0.0-rc.11: + dependencies: + '@oxc-project/types': 0.122.0 + '@rolldown/pluginutils': 1.0.0-rc.11 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.11 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.11 + '@rolldown/binding-darwin-x64': 1.0.0-rc.11 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.11 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.11 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.11 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.11 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.11 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.11 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.11 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.11 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.11 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.11 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.11 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.11 + rollup-plugin-inject@3.0.2: dependencies: estree-walker: 0.6.1 @@ -3936,6 +4388,10 @@ snapshots: react: 19.2.4 use-sync-external-store: 1.6.0(react@19.2.4) + tailwindcss@4.2.2: {} + + tapable@2.3.2: {} + timers-ext@0.1.8: dependencies: es5-ext: 0.10.64 @@ -3969,13 +4425,13 @@ snapshots: type@2.7.3: {} - typescript-eslint@8.57.1(eslint@9.39.4)(typescript@5.9.3): + typescript-eslint@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@9.39.4)(typescript@5.9.3) - eslint: 9.39.4 + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -4012,7 +4468,7 @@ snapshots: dependencies: react: 19.2.4 - vite@8.0.1(@types/node@24.12.0): + vite@8.0.1(@types/node@24.12.0)(esbuild@0.19.12)(jiti@2.6.1): dependencies: lightningcss: 1.32.0 picomatch: 4.0.3 @@ -4021,7 +4477,9 @@ snapshots: tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.12.0 + esbuild: 0.19.12 fsevents: 2.3.3 + jiti: 2.6.1 which@2.0.2: dependencies: