From 02351f396ae7f53828ed8348a63d9d32ecaa5be0 Mon Sep 17 00:00:00 2001 From: Chaithra S Date: Wed, 25 Mar 2026 02:00:38 +0530 Subject: [PATCH] Add voting UI, flow & components --- apps/web/package.json | 5 + apps/web/public/cosc.png | Bin 0 -> 16464 bytes apps/web/public/dk24.png | Bin 0 -> 8302 bytes apps/web/public/favicon.svg | 1 - apps/web/public/icons.svg | 24 - apps/web/src/App.tsx | 265 +++++---- apps/web/src/components/CompletionScreen.tsx | 77 +++ apps/web/src/components/LoginScreen.tsx | 113 ++++ apps/web/src/components/ProgressScreen.tsx | 192 +++++++ apps/web/src/components/RatingScreen.tsx | 182 +++++++ apps/web/src/components/ScannerScreen.tsx | 162 ++++++ apps/web/src/index.css | 119 +--- apps/web/vite.config.ts | 3 + package-lock.json | 115 ++++ pnpm-lock.yaml | 538 +++++++++++++++++-- 15 files changed, 1513 insertions(+), 283 deletions(-) create mode 100644 apps/web/public/cosc.png create mode 100644 apps/web/public/dk24.png delete mode 100644 apps/web/public/favicon.svg delete mode 100644 apps/web/public/icons.svg create mode 100644 apps/web/src/components/CompletionScreen.tsx create mode 100644 apps/web/src/components/LoginScreen.tsx create mode 100644 apps/web/src/components/ProgressScreen.tsx create mode 100644 apps/web/src/components/RatingScreen.tsx create mode 100644 apps/web/src/components/ScannerScreen.tsx create mode 100644 package-lock.json 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 0000000000000000000000000000000000000000..8bcde57cad826b82e0cd3a6dc2abffe720868ea0 GIT binary patch literal 16464 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 \ 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: