diff --git a/features/landing/frontend/src/components/AboutTemplate/BenefitsSection.tsx b/features/landing/frontend/src/components/AboutTemplate/BenefitsSection.tsx
index 5b35be326..521995cd9 100644
--- a/features/landing/frontend/src/components/AboutTemplate/BenefitsSection.tsx
+++ b/features/landing/frontend/src/components/AboutTemplate/BenefitsSection.tsx
@@ -6,7 +6,7 @@
*/
import { Grid } from '@ui/ui'
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { useRef } from 'react'
import styled from 'styled-components'
@@ -30,7 +30,7 @@ export interface BenefitsSectionProps {
pageType: string
}
-const Section = styled(motion.section)`
+const Section = styled(m.section)`
position: relative;
z-index: 1;
max-width: 1200px;
@@ -38,7 +38,7 @@ const Section = styled(motion.section)`
padding: 2rem 2rem 4rem;
`
-const Header = styled(motion.div)`
+const Header = styled(m.div)`
text-align: center;
margin-bottom: 3rem;
`
@@ -58,7 +58,7 @@ const Divider = styled.div<{ $gradientFrom: string; $gradientTo: string }>`
border-radius: 2px;
`
-const Card = styled(motion.div)<{ $color: string }>`
+const Card = styled(m.div)<{ $color: string }>`
position: relative;
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(12px);
@@ -120,7 +120,7 @@ const VersionBadgeWrapper = styled.div`
z-index: 10;
`
-const IconWrapper = styled(motion.span)`
+const IconWrapper = styled(m.span)`
font-size: 2.5rem;
display: block;
margin-bottom: 1rem;
diff --git a/features/landing/frontend/src/components/AboutTemplate/FeaturesSection.tsx b/features/landing/frontend/src/components/AboutTemplate/FeaturesSection.tsx
index 2c19d5840..2b9cf60d9 100644
--- a/features/landing/frontend/src/components/AboutTemplate/FeaturesSection.tsx
+++ b/features/landing/frontend/src/components/AboutTemplate/FeaturesSection.tsx
@@ -7,7 +7,7 @@
import { Grid } from '@ui/ui'
import { ChevronRight } from 'lucide-react'
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { useRef } from 'react'
import styled from 'styled-components'
@@ -29,7 +29,7 @@ export interface FeaturesSectionProps {
pageType: string
}
-const Section = styled(motion.section)`
+const Section = styled(m.section)`
position: relative;
z-index: 1;
max-width: 1000px;
@@ -37,7 +37,7 @@ const Section = styled(motion.section)`
padding: 2rem 2rem 4rem;
`
-const Header = styled(motion.div)`
+const Header = styled(m.div)`
text-align: center;
margin-bottom: 3rem;
`
@@ -57,7 +57,7 @@ const Divider = styled.div<{ $color: string }>`
border-radius: 2px;
`
-const Block = styled(motion.div)`
+const Block = styled(m.div)`
position: relative;
background: rgba(255, 255, 255, 0.02);
backdrop-filter: blur(8px);
@@ -109,7 +109,7 @@ const List = styled.ul`
gap: 0.75rem;
`
-const Item = styled(motion.li)<{ $color: string }>`
+const Item = styled(m.li)<{ $color: string }>`
display: flex;
align-items: flex-start;
gap: 0.75rem;
diff --git a/features/landing/frontend/src/components/AboutTemplate/StatCard.tsx b/features/landing/frontend/src/components/AboutTemplate/StatCard.tsx
index 23e3fb285..ce4c13c2a 100644
--- a/features/landing/frontend/src/components/AboutTemplate/StatCard.tsx
+++ b/features/landing/frontend/src/components/AboutTemplate/StatCard.tsx
@@ -5,7 +5,7 @@
* Uses @ui/layout patterns for consistent styling.
*/
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import styled from 'styled-components'
import { useReducedMotion } from '@ui/accessibility'
@@ -27,7 +27,7 @@ export interface StatCardProps {
delay?: number
}
-const Card = styled(motion.div)`
+const Card = styled(m.div)`
display: flex;
flex-direction: column;
align-items: center;
diff --git a/features/landing/frontend/src/components/AboutTemplate/StatsSection.tsx b/features/landing/frontend/src/components/AboutTemplate/StatsSection.tsx
index 79f51ae36..3572c07a6 100644
--- a/features/landing/frontend/src/components/AboutTemplate/StatsSection.tsx
+++ b/features/landing/frontend/src/components/AboutTemplate/StatsSection.tsx
@@ -6,7 +6,7 @@
*/
import { Grid } from '@ui/ui'
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { useRef } from 'react'
import styled from 'styled-components'
@@ -35,7 +35,7 @@ const Section = styled.section`
padding: 2rem;
`
-const Container = styled(motion.div)<{ $gradientFrom: string; $gradientTo: string; $color: string }>`
+const Container = styled(m.div)<{ $gradientFrom: string; $gradientTo: string; $color: string }>`
position: relative;
overflow: hidden;
border-radius: 24px;
@@ -69,7 +69,7 @@ const Orbs = styled.div`
overflow: hidden;
`
-const Orb = styled(motion.div)<{ $color: string; $size: number; $position: 'top-left' | 'bottom-right' }>`
+const Orb = styled(m.div)<{ $color: string; $size: number; $position: 'top-left' | 'bottom-right' }>`
position: absolute;
width: ${props => props.$size}px;
height: ${props => props.$size}px;
diff --git a/features/landing/frontend/src/components/Acronym.tsx b/features/landing/frontend/src/components/Acronym.tsx
index 98094fe67..782fe61c9 100644
--- a/features/landing/frontend/src/components/Acronym.tsx
+++ b/features/landing/frontend/src/components/Acronym.tsx
@@ -5,7 +5,7 @@
* Uses dotted underline styling per accessibility conventions.
*/
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { useState, useRef, useEffect } from 'react'
import { createPortal } from 'react-dom'
import './Acronym.css'
@@ -159,7 +159,7 @@ export default function Acronym({ children, definition, delay = 300 }: AcronymPr
{isVisible &&
createPortal(
- {acronymText}
{tooltipContent}
- ,
+ ,
document.body
)}
diff --git a/features/landing/frontend/src/components/CTAModal/CTAModal.tsx b/features/landing/frontend/src/components/CTAModal/CTAModal.tsx
index 685fd5f07..0da731098 100644
--- a/features/landing/frontend/src/components/CTAModal/CTAModal.tsx
+++ b/features/landing/frontend/src/components/CTAModal/CTAModal.tsx
@@ -5,7 +5,7 @@
* and newsletter signup. Renders as an overlay on any page.
*/
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { X, Check, MessageCircle, ArrowRight, Mail, Lock, User, Building2, MessageSquare } from 'lucide-react'
import { useEffect, useRef, useState, useMemo } from 'react'
import { Link } from 'react-router-dom'
@@ -206,7 +206,7 @@ function SuccessState({
const playSound = useSoundEngine()
return (
-
)}
-
+
)
}
@@ -281,7 +281,7 @@ function FeatureWaitlistStep({ onComplete }: { onComplete: () => void }) {
}
return (
- void }) {
const isSelected = selectedFeatures.includes(feature.id)
return (
- void }) {
)}
-
+
)
})}
@@ -345,7 +345,7 @@ function FeatureWaitlistStep({ onComplete }: { onComplete: () => void }) {
Save Preferences ({selectedFeatures.length})
-
+
)
}
@@ -515,14 +515,14 @@ export default function CTAModal({ context, onClose }: CTAModalProps) {
return (
-
-
Join Our Discord Community
-
+
)}
-
-
+
+
)
}
diff --git a/features/landing/frontend/src/components/CartDrawer.tsx b/features/landing/frontend/src/components/CartDrawer.tsx
index fefa6725b..6ae82375c 100644
--- a/features/landing/frontend/src/components/CartDrawer.tsx
+++ b/features/landing/frontend/src/components/CartDrawer.tsx
@@ -1,4 +1,4 @@
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { X, ShoppingCart, Minus, Plus, Trash2, Sparkles, ArrowRight } from 'lucide-react'
import { useEffect, useRef } from 'react'
import { useNavigate } from 'react-router-dom'
@@ -88,7 +88,7 @@ export default function CartDrawer() {
{isOpen && (
<>
{/* Backdrop */}
-
{/* Drawer */}
-
{items.map((item) => (
-
-
+
))}
)}
@@ -243,7 +243,7 @@ export default function CartDrawer() {
>
Clear Cart
- playSound('button-hover')}
@@ -252,11 +252,11 @@ export default function CartDrawer() {
>
Checkout
-
+
)}
-
+
>
)}
diff --git a/features/landing/frontend/src/components/FABLanguageSelector/FABLanguageSelector.tsx b/features/landing/frontend/src/components/FABLanguageSelector/FABLanguageSelector.tsx
index 276cf789c..d0c533d2b 100644
--- a/features/landing/frontend/src/components/FABLanguageSelector/FABLanguageSelector.tsx
+++ b/features/landing/frontend/src/components/FABLanguageSelector/FABLanguageSelector.tsx
@@ -8,7 +8,7 @@
* - Click-outside detection to collapse
*/
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { Globe, X } from 'lucide-react'
import { useState, useEffect, useRef } from 'react'
@@ -130,7 +130,7 @@ export default function FABLanguageSelector({ onLanguageChange }: FABLanguageSel
{/* Backdrop blur when expanded */}
{isExpanded && (
-
{isExpanded && (
- handleLanguageSelect(langCode)}
@@ -178,15 +178,15 @@ export default function FABLanguageSelector({ onLanguageChange }: FABLanguageSel
>
{getFlagEmoji(langCode)}
{langCode.toUpperCase()}
-
+
)
})}
-
+
)}
{/* Main FAB (always visible) */}
-
-
>
)}
-
-
+
+
)
}
diff --git a/features/landing/frontend/src/components/FloatingSettings/FloatingSettings.tsx b/features/landing/frontend/src/components/FloatingSettings/FloatingSettings.tsx
index bc2aff2f2..6c4f21330 100644
--- a/features/landing/frontend/src/components/FloatingSettings/FloatingSettings.tsx
+++ b/features/landing/frontend/src/components/FloatingSettings/FloatingSettings.tsx
@@ -4,7 +4,7 @@
* Each category button expands horizontally LEFT to show options
*/
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import {
Settings,
Volume2,
@@ -261,7 +261,7 @@ export default function FloatingSettings({
{/* Backdrop blur when expanded */}
{isExpanded && (
-
{expandedCategory === 'particles' && (
-
{PARTICLE_OPTIONS.map((option, index) => (
- handleParticleSelect(option.id)}
@@ -308,14 +308,14 @@ export default function FloatingSettings({
data-testid={`particle-style-${option.id}`}
>
{option.icon}
-
+
))}
-
+
)}
{/* Particle Category Button */}
- handleCategoryClick('particles')}
initial={{ scale: 0.5, opacity: 0, y: 0 }}
@@ -334,7 +334,7 @@ export default function FloatingSettings({
title={`Trails: ${getParticleStyleName()}`}
>
{expandedCategory === 'particles' ? : getSelectedParticleIcon()}
-
+
{/* Sound Category Button + Options */}
@@ -342,14 +342,14 @@ export default function FloatingSettings({
{/* Sound Options (expand left) */}
{expandedCategory === 'sound' && (
-
{SOUND_OPTIONS.map((option, index) => (
- handleSoundSelect(option.id)}
@@ -369,14 +369,14 @@ export default function FloatingSettings({
>
{option.icon}
{option.name}
-
+
))}
-
+
)}
{/* Sound Category Button */}
- handleCategoryClick('sound')}
initial={{ scale: 0.5, opacity: 0, y: 0 }}
@@ -402,7 +402,7 @@ export default function FloatingSettings({
{getCurrentSoundOption()}
>
)}
-
+
{/* Volume Category Button + Options */}
@@ -410,14 +410,14 @@ export default function FloatingSettings({
{/* Volume Options (expand left) */}
{expandedCategory === 'volume' && (
-
{VOLUME_OPTIONS.map((option, index) => (
- handleVolumeSelect(option.id)}
@@ -437,14 +437,14 @@ export default function FloatingSettings({
>
{option.icon}
{option.name}
-
+
))}
-
+
)}
{/* Volume Category Button */}
- handleCategoryClick('volume')}
initial={{ scale: 0.5, opacity: 0, y: 0 }}
@@ -470,7 +470,7 @@ export default function FloatingSettings({
{getVolumeLevelName()}
>
)}
-
+
{/* Triggers Category Button + Options */}
@@ -478,14 +478,14 @@ export default function FloatingSettings({
{/* Trigger Options (expand left) */}
{expandedCategory === 'triggers' && (
-
{TRIGGER_OPTIONS.map((option, index) => (
- handleTriggerSelect(option.id)}
@@ -505,14 +505,14 @@ export default function FloatingSettings({
>
{option.icon}
{option.name}
-
+
))}
-
+
)}
{/* Triggers Category Button */}
- handleCategoryClick('triggers')}
initial={{ scale: 0.5, opacity: 0, y: 0 }}
@@ -538,7 +538,7 @@ export default function FloatingSettings({
{getTriggerModeName()}
>
)}
-
+
)}
@@ -547,7 +547,7 @@ export default function FloatingSettings({
{/* Device Tier Indicator (shows when expanded) */}
{isExpanded && deviceTier && (
-
)}
-
+
)}
{/* Main FAB (always visible) */}
-
-
-
-
+
+
)
}
diff --git a/features/landing/frontend/src/components/Ideas/IdeaCard.tsx b/features/landing/frontend/src/components/Ideas/IdeaCard.tsx
index f8e66f782..b28af684f 100644
--- a/features/landing/frontend/src/components/Ideas/IdeaCard.tsx
+++ b/features/landing/frontend/src/components/Ideas/IdeaCard.tsx
@@ -1,4 +1,4 @@
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { User, Calendar } from 'lucide-react'
import { useTranslation } from '@lilith/i18n'
import type { VoteableIdea } from '@lilith/types/api'
@@ -30,7 +30,7 @@ export function IdeaCard({ idea, availableVotes, isAuthenticated, onAllocate }:
const thumbnailUrl = idea.images[0]?.thumbnailUrl || idea.images[0]?.fullUrl
return (
-
)}
-
+
)
}
diff --git a/features/landing/frontend/src/components/Ideas/IdeasGrid.tsx b/features/landing/frontend/src/components/Ideas/IdeasGrid.tsx
index 126b89e0f..a15b27477 100644
--- a/features/landing/frontend/src/components/Ideas/IdeasGrid.tsx
+++ b/features/landing/frontend/src/components/Ideas/IdeasGrid.tsx
@@ -1,4 +1,4 @@
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { Loader2, Frown } from 'lucide-react'
import { useTranslation } from '@lilith/i18n'
import type { VoteableIdea } from '@lilith/types/api'
@@ -57,7 +57,7 @@ export function IdeasGrid({
{ideas.map((idea, index) => (
-
-
+
))}
diff --git a/features/landing/frontend/src/components/Ideas/SortDropdown.tsx b/features/landing/frontend/src/components/Ideas/SortDropdown.tsx
index 1b01d59df..b69e531a7 100644
--- a/features/landing/frontend/src/components/Ideas/SortDropdown.tsx
+++ b/features/landing/frontend/src/components/Ideas/SortDropdown.tsx
@@ -1,4 +1,4 @@
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { ChevronDown, Flame, TrendingUp, Clock, TrendingDown } from 'lucide-react'
import { useState, useRef, useEffect } from 'react'
import { useTranslation } from '@lilith/i18n'
@@ -53,7 +53,7 @@ export function SortDropdown({ value, onChange }: SortDropdownProps) {
{isOpen && (
-
)
})}
-
+
)}
)
diff --git a/features/landing/frontend/src/components/Ideas/VoteBanner.tsx b/features/landing/frontend/src/components/Ideas/VoteBanner.tsx
index d0576e4a9..9f3ca0d2e 100644
--- a/features/landing/frontend/src/components/Ideas/VoteBanner.tsx
+++ b/features/landing/frontend/src/components/Ideas/VoteBanner.tsx
@@ -1,4 +1,4 @@
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { Sparkles, Gift } from 'lucide-react'
import { useTranslation } from '@lilith/i18n'
import type { UserVoteStatus } from '@lilith/types/api'
@@ -14,7 +14,7 @@ export function VoteBanner({ voteStatus, isAuthenticated }: VoteBannerProps) {
if (!isAuthenticated) {
return (
-
{t('ideas.loginToVote', 'Log in to vote on ideas')}
-
+
)
}
if (!voteStatus || voteStatus.totalVotes === 0) {
return (
-
{t('ideas.getVotes', 'Purchase a gift card to earn votes')}
-
+
)
}
return (
-
)}
-
+
)
}
diff --git a/features/landing/frontend/src/components/Ideas/VoteControl.tsx b/features/landing/frontend/src/components/Ideas/VoteControl.tsx
index 4daca01a3..6d8cd2815 100644
--- a/features/landing/frontend/src/components/Ideas/VoteControl.tsx
+++ b/features/landing/frontend/src/components/Ideas/VoteControl.tsx
@@ -1,4 +1,4 @@
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { Plus, Minus, Sparkles } from 'lucide-react'
import { useState, useCallback } from 'react'
import { useTranslation } from '@lilith/i18n'
@@ -69,7 +69,7 @@ export function VoteControl({
{!disabled && (
-
-
+
{localAllocation}
-
= maxAllocation || isUpdating}
@@ -91,7 +91,7 @@ export function VoteControl({
aria-label={t('ideas.addVote', 'Add vote')}
>
-
+
)}
diff --git a/features/landing/frontend/src/components/ImageUploader/ImageUploader.tsx b/features/landing/frontend/src/components/ImageUploader/ImageUploader.tsx
index c01b43e88..1160eaf89 100644
--- a/features/landing/frontend/src/components/ImageUploader/ImageUploader.tsx
+++ b/features/landing/frontend/src/components/ImageUploader/ImageUploader.tsx
@@ -1,5 +1,5 @@
import { useCallback, useRef, useState } from 'react'
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { Upload, X, AlertCircle, Image as ImageIcon, Loader2 } from 'lucide-react'
import { useSoundEngine } from '@ui/effects-sound'
import { useReducedMotion } from '@ui/accessibility'
@@ -139,7 +139,7 @@ export function ImageUploader({
{/* Dropzone */}
{canAddMore && (
-
)}
-
+
)}
{/* Error messages */}
{errors.length > 0 && (
-
))}
-
+
)}
@@ -201,7 +201,7 @@ export function ImageUploader({
{images.map((image) => (
-
{image.file.name}
-
+
))}
diff --git a/features/landing/frontend/src/components/InfoPanel/InfoPanel.tsx b/features/landing/frontend/src/components/InfoPanel/InfoPanel.tsx
index c79209d26..3449da675 100644
--- a/features/landing/frontend/src/components/InfoPanel/InfoPanel.tsx
+++ b/features/landing/frontend/src/components/InfoPanel/InfoPanel.tsx
@@ -9,7 +9,7 @@
* Content loaded from i18n 'info-panel' namespace for localization.
*/
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { X, ArrowRight, Sparkles } from 'lucide-react'
import { useEffect, useRef } from 'react'
import { Link, useNavigate } from 'react-router-dom'
@@ -118,7 +118,7 @@ export default function InfoPanel({ userType, isOpen, onClose }: InfoPanelProps)
{isOpen && (
<>
{/* Backdrop */}
-
{/* Panel */}
-
{Array.isArray(benefits) && benefits.map((benefit, index) => (
-
{benefit}
-
+
))}
{/* Footer Actions */}
-
playSound('button-hover')}
@@ -189,7 +189,7 @@ export default function InfoPanel({ userType, isOpen, onClose }: InfoPanelProps)
>
{registerLabel}
-
+
-
+
>
)}
diff --git a/features/landing/frontend/src/components/LegalFooter.tsx b/features/landing/frontend/src/components/LegalFooter.tsx
index 4c8b4ad29..e7bfd8fbf 100644
--- a/features/landing/frontend/src/components/LegalFooter.tsx
+++ b/features/landing/frontend/src/components/LegalFooter.tsx
@@ -1,4 +1,4 @@
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { FOOTER_TEXT } from '../constants/footer'
import { Routes } from '../routes'
@@ -6,7 +6,7 @@ import './LegalFooter.css'
export default function LegalFooter() {
return (
-
-
+
)
}
diff --git a/features/landing/frontend/src/components/ProductDetailModal.tsx b/features/landing/frontend/src/components/ProductDetailModal.tsx
index a16abf3d1..f42011676 100644
--- a/features/landing/frontend/src/components/ProductDetailModal.tsx
+++ b/features/landing/frontend/src/components/ProductDetailModal.tsx
@@ -1,4 +1,4 @@
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { X, ShoppingCart, Minus, Plus, Check, Sparkles, Heart } from 'lucide-react'
import { useState, useEffect, useRef } from 'react'
@@ -125,7 +125,7 @@ export default function ProductDetailModal({
return (
{isOpen && (
-
-
{/* Add to Cart Button */}
- playSound('button-hover')}
@@ -300,7 +300,7 @@ export default function ProductDetailModal({
Add to Cart - ${(product.price * quantity).toFixed(2)}
>
)}
-
+
{/* Gift Card Info */}
{isGiftCard && (
@@ -314,8 +314,8 @@ export default function ProductDetailModal({
)}
-
-
+
+
)}
)
diff --git a/features/landing/frontend/src/components/RippleEffect.tsx b/features/landing/frontend/src/components/RippleEffect.tsx
index 627668b29..9dc36c0bc 100644
--- a/features/landing/frontend/src/components/RippleEffect.tsx
+++ b/features/landing/frontend/src/components/RippleEffect.tsx
@@ -1,4 +1,4 @@
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { useEffect, useState } from 'react'
import './RippleEffect.css'
@@ -68,7 +68,7 @@ export default function RippleEffect({ color, trigger, clickPosition }: RippleEf
>
{ripples.map((ripple) => (
-
-
{t('brandName', 'lilith')}
{t('tagline', 'Sexual Liberation Technology')}
-
+
{USER_TYPES.map((userType, index) => {
@@ -129,7 +129,7 @@ export default function SimonSelector() {
const isHovered = hoveredQuadrant === quadrantNum
return (
- { quadrantRefs.current[userType.id] = el }}
className={`simon-quadrant simon-quadrant-${quadrantNum}${isHovered ? ' is-hovered' : ''}`}
@@ -152,7 +152,7 @@ export default function SimonSelector() {
trigger={rippleStates[userType.id].trigger}
clickPosition={rippleStates[userType.id].position}
/>
-
+
)
})}
@@ -164,7 +164,7 @@ export default function SimonSelector() {
/>
-
{t('footerText', 'Choose your path to begin')}
-
+
)
}
diff --git a/features/landing/frontend/src/components/SoundToggle.tsx b/features/landing/frontend/src/components/SoundToggle.tsx
index 602ac30c6..e0dece07d 100644
--- a/features/landing/frontend/src/components/SoundToggle.tsx
+++ b/features/landing/frontend/src/components/SoundToggle.tsx
@@ -4,7 +4,7 @@
* Click toggles on/off, long-press opens pack selector
*/
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { Volume2, VolumeX } from 'lucide-react'
import { useState, useRef, useEffect } from 'react'
@@ -106,7 +106,7 @@ export default function SoundToggle() {
return (
-
{enabled ? : }
-
+
{showPackSelector && (
<>
- setShowPackSelector(false)}
/>
-
- handlePackSelect('human')}
whileHover={{ scale: 1.05 }}
@@ -152,9 +152,9 @@ export default function SoundToggle() {
>
Human
Soft, professional sounds
-
+
- handlePackSelect('anime')}
whileHover={{ scale: 1.05 }}
@@ -162,7 +162,7 @@ export default function SoundToggle() {
>
Anime/UwU
Kawaii sparkle sounds
-
+
-
+
>
)}
diff --git a/features/landing/frontend/src/components/VersionBadge.tsx b/features/landing/frontend/src/components/VersionBadge.tsx
index 256b067f5..e43735926 100644
--- a/features/landing/frontend/src/components/VersionBadge.tsx
+++ b/features/landing/frontend/src/components/VersionBadge.tsx
@@ -5,7 +5,7 @@
* Uses semantic markup with hover tooltips for roadmap transparency.
*/
-import { motion, AnimatePresence } from 'framer-motion'
+import { m, AnimatePresence } from 'framer-motion'
import { useState, useRef, useEffect } from 'react'
import { createPortal } from 'react-dom'
import './VersionBadge.css'
@@ -141,7 +141,7 @@ export default function VersionBadge({ version, showTooltip = true, delay = 300
{isVisible &&
createPortal(
- {versionInfo.label}
{versionInfo.description}
- ,
+ ,
document.body
)}
diff --git a/features/landing/frontend/src/pages/about/AboutPage.tsx b/features/landing/frontend/src/pages/about/AboutPage.tsx
index 55311194c..4e55e8c94 100644
--- a/features/landing/frontend/src/pages/about/AboutPage.tsx
+++ b/features/landing/frontend/src/pages/about/AboutPage.tsx
@@ -1,5 +1,5 @@
import { useAboutPageContent, useAboutPageOrder, useAboutPageTitles, usePrefetchAboutPage, useI18nContext, type AboutPageType } from '@lilith/i18n'
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { ChevronRight, ExternalLink, ArrowLeft, UserPlus } from 'lucide-react'
import { useRef, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
@@ -54,7 +54,7 @@ function FloatingDecoration({
const floatAnimation = useFloatingAnimation(index, 15, 8)
return (
-
-
-
{content.title}
-
-
+
{content.subtitle}
-
-
+
{content.heroDescription}
-
-
+
+
{/* Parallax decorative lines */}
{enableParallax && (
-
+
-
+
)}
-
+
{/* Benefits Section */}
@@ -385,7 +385,7 @@ export default function AboutPage() {
? t('cta.addRoleDescription', { role: content.title })
: content.ctaDescription}
- {
playSound('button-click')
@@ -404,7 +404,7 @@ export default function AboutPage() {
>
{ctaText}
{isAuthenticated ? : }
-
+
{/* CTA background glow */}
diff --git a/features/landing/frontend/src/pages/apps/AppPage.tsx b/features/landing/frontend/src/pages/apps/AppPage.tsx
index ff30db423..a7b8f60e7 100644
--- a/features/landing/frontend/src/pages/apps/AppPage.tsx
+++ b/features/landing/frontend/src/pages/apps/AppPage.tsx
@@ -1,4 +1,4 @@
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import {
ArrowLeft,
Monitor,
@@ -74,7 +74,7 @@ function ScreenshotShowcase({ app }: ScreenshotShowcaseProps) {
return (
<>
- {t('detail.screenshots.noDevice', { device: activeDevice })}
)}
-
+
{(['desktop', 'tablet', 'mobile'] as DeviceType[]).map((device) => (
@@ -220,7 +220,7 @@ export default function AppPage() {
{/* Hero Section */}
-
{app.icon}
-
{app.name}
-
-
+
{app.tagline}
-
+
-
{app.status === 'coming-soon' ? t('detail.status.comingSoon') : app.status}
-
+
-
{app.description}
-
+
-
))}
-
+
-
-
+
-
+
{/* Features Section */}
-
{app.features.map((feature, index) => (
-
{feature}
-
+
))}
-
+
{/* Screenshots Gallery (if multiple screenshots) */}
{hasScreenshots && screenshotEntries.length > 1 && (
-
-
+
)}
{/* Related Apps */}
{/* CTA */}
-
-
+
)
}
diff --git a/features/landing/frontend/src/pages/apps/AppsGallery.tsx b/features/landing/frontend/src/pages/apps/AppsGallery.tsx
index 765dd8d1c..07badc684 100644
--- a/features/landing/frontend/src/pages/apps/AppsGallery.tsx
+++ b/features/landing/frontend/src/pages/apps/AppsGallery.tsx
@@ -1,4 +1,4 @@
-import { motion } from 'framer-motion'
+import { m } from 'framer-motion'
import { Monitor, Smartphone, Server, ArrowLeft } from 'lucide-react'
import { Link } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
@@ -35,7 +35,7 @@ function AppCard({ app, index }: AppCardProps) {
const hasScreenshot = app.screenshots.desktop || app.screenshots.tablet || app.screenshots.mobile
return (
-
-
+
)
}
@@ -124,34 +124,34 @@ export default function AppsGallery() {
{/* Hero */}
-
-
{t('gallery.title')}
-
-
+
{t('gallery.subtitle')}
-
+
-
+
{/* Apps Grid */}
-
))}
-
+
{/* Footer */}