Этот коммит содержится в:
Constantin Rusu 2024-12-07 10:32:46 +00:00
родитель 2eb487f048
Коммит f9f1732b78
21 изменённых файлов: 1342 добавлений и 100 удалений

Просмотреть файл

@ -1,5 +1,33 @@
# Welcome to your Lovable project
## Mission Brief: Operation Mathematical Persuasion
**CLEARANCE LEVEL**: TOP SECRET
**MISSION STATUS**: ACTIVE
Dear Agent,
Your mission, should you choose to accept it, is to execute Operation Mathematical Persuasion: convincing the general population that 2+2=5. This is a highly sophisticated psychological operation requiring finesse, creativity, and unwavering dedication.
**Resources at your disposal:**
- A team of cognitive psychology experts
- Advanced social media manipulation algorithms
- Network of influential mathematics professors
- State-of-the-art reality distortion technology
- Quantum uncertainty specialists
**Key Objectives:**
1. Gradually introduce doubt into basic arithmetic
2. Deploy sophisticated mathematical proofs with intentional errors
3. Establish alternative mathematical frameworks
4. Influence key educational institutions
Remember: Reality is malleable, truth is negotiable, and mathematics is our playground.
Good luck, Agent. The future of mathematical chaos depends on you.
---
## Project info
**URL**: https://lovable.dev/projects/81423a31-1e32-4da1-b996-65839f426144

Просмотреть файл

@ -8,7 +8,8 @@
"build": "vite build",
"build:dev": "vite build --mode development",
"lint": "eslint .",
"preview": "vite preview"
"preview": "vite preview --port 3000 --host",
"start": "vite preview --port 3000 --host"
},
"dependencies": {
"@hookform/resolvers": "^3.9.0",

Двоичный файл не отображается.

Двоичные данные
public/audio/agent-torres-april.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/click1.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/click2.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/dr-chen-january.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/dr-webb-february.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/mixkit-modern-technology-select-3124.wav Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/mixkit-retro-arcade-casino-notification-211.wav Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/mixkit-sci-fi-click-900.wav Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/audio/prof-morrison-march.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/pixabay-suspense-265381.mp3 Обычный файл

Двоичный файл не отображается.

Двоичные данные
public/tension-background.mp3 Обычный файл

Двоичный файл не отображается.

53
src/components/GameBackground.tsx Обычный файл
Просмотреть файл

@ -0,0 +1,53 @@
import { useEffect, useState } from "react";
export const GameBackground = () => {
const [audioStarted, setAudioStarted] = useState(false);
useEffect(() => {
// Only start audio after user interaction
const handleFirstInteraction = () => {
if (!audioStarted) {
const audio = new Audio("/tension-background.mp3");
audio.loop = true;
audio.volume = 0.3;
audio.play().catch(console.error);
setAudioStarted(true);
document.removeEventListener("click", handleFirstInteraction);
}
};
document.addEventListener("click", handleFirstInteraction);
return () => document.removeEventListener("click", handleFirstInteraction);
}, [audioStarted]);
return (
<div className="fixed inset-0 -z-10 overflow-hidden">
{/* Animated grid */}
<div className="absolute inset-0 bg-[linear-gradient(rgba(0,0,0,0.8)_2px,transparent_2px),linear-gradient(90deg,rgba(0,0,0,0.8)_2px,transparent_2px)] bg-[size:40px_40px] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000,transparent)] opacity-20"></div>
{/* Floating numbers */}
<div className="absolute inset-0">
{[...Array(20)].map((_, i) => (
<div
key={i}
className="absolute text-yellow-500/20 text-4xl font-bold animate-float"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 5}s`,
animationDuration: `${15 + Math.random() * 10}s`
}}
>
{Math.random() > 0.5 ? "2+2=5" : "5"}
</div>
))}
</div>
{/* Gradient overlay */}
<div className="absolute inset-0 bg-gradient-to-b from-gray-900/90 to-gray-800/90"></div>
{/* Animated pulse */}
<div className="absolute inset-0 animate-pulse-slow bg-gradient-radial from-yellow-500/5 to-transparent"></div>
</div>
);
};

133
src/components/MonthTransition.tsx Обычный файл
Просмотреть файл

@ -0,0 +1,133 @@
import { useEffect, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
export enum TransitionStyle {
FADE = "fade",
TYPEWRITER = "typewriter",
SPLIT_SCREEN = "split-screen",
MATRIX = "matrix",
NUMBER_CYCLE = "number-cycle"
}
interface MonthTransitionProps {
month: string;
onComplete: () => void;
style: TransitionStyle;
}
// Create separate components for each style
const FadeTransition = ({ month }: { month: string }) => (
<Card className="bg-transparent border-none shadow-none">
<CardContent className="flex items-center justify-center">
<div className="text-6xl font-bold text-yellow-500 animate-month-transition">
{month}
</div>
</CardContent>
</Card>
);
const TypewriterTransition = ({ month }: { month: string }) => (
<div className="relative">
<div className="overflow-hidden whitespace-nowrap border-r-4 border-yellow-500 pr-1 text-6xl font-bold text-yellow-500 animate-typewriter animate-cursor-blink">
{month}
</div>
</div>
);
const SplitScreenTransition = ({ month }: { month: string }) => (
<>
<div className="absolute inset-0 flex">
<div className="w-1/2 bg-yellow-500 animate-slide-left" />
<div className="w-1/2 bg-yellow-500 animate-slide-right" />
</div>
<div className="z-10 text-6xl font-bold text-black">
{month}
</div>
</>
);
const MatrixTransition = ({ month }: { month: string }) => (
<>
<div className="absolute inset-0 overflow-hidden">
{[...Array(20)].map((_, i) => (
<div
key={i}
className="absolute text-yellow-500/30 text-2xl animate-rain"
style={{
left: `${i * 5}%`,
animationDelay: `${Math.random() * 2}s`
}}
>
2+2=5
</div>
))}
</div>
<div className="relative z-10">
<div className="text-6xl font-bold text-yellow-500 animate-glitch">
{month}
</div>
</div>
</>
);
const NumberCycleTransition = ({ month }: { month: string }) => {
const [numbers, setNumbers] = useState(
Array(month.length).fill('0')
);
useEffect(() => {
const interval = setInterval(() => {
setNumbers(prev => prev.map(() =>
Math.floor(Math.random() * 10).toString()
));
}, 100);
setTimeout(() => clearInterval(interval), 2000);
return () => clearInterval(interval);
}, [month.length]);
return (
<div className="flex flex-col items-center">
<div className="flex gap-2 mb-8">
{numbers.map((num, i) => (
<div key={i} className="text-4xl text-yellow-500/50 animate-cycle w-[1ch] text-center">
{num}
</div>
))}
</div>
<div className="text-6xl font-bold text-yellow-500">
{month}
</div>
</div>
);
};
export const MonthTransition = ({ month, onComplete, style }: MonthTransitionProps) => {
useEffect(() => {
const timer = setTimeout(onComplete, 3000);
return () => clearTimeout(timer);
}, [onComplete]);
const renderTransition = () => {
switch (style) {
case TransitionStyle.FADE:
return <FadeTransition month={month} />;
case TransitionStyle.TYPEWRITER:
return <TypewriterTransition month={month} />;
case TransitionStyle.SPLIT_SCREEN:
return <SplitScreenTransition month={month} />;
case TransitionStyle.MATRIX:
return <MatrixTransition month={month} />;
case TransitionStyle.NUMBER_CYCLE:
return <NumberCycleTransition month={month} />;
default:
return <FadeTransition month={month} />;
}
};
return (
<div className="absolute inset-0 flex items-center justify-center animate-transition-container">
{renderTransition()}
</div>
);
};

Просмотреть файл

@ -4,16 +4,16 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
secondary:
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive:
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
outline: "text-foreground",
},
},

Разница между файлами не показана из-за своего большого размера Загрузить разницу

37
src/utils/audio.ts Обычный файл
Просмотреть файл

@ -0,0 +1,37 @@
const CLICK_SOUNDS = [
"/audio/click1.mp3",
"/audio/click2.mp3"
];
class AudioPlayer {
private static instance: AudioPlayer;
private audioElements: { [key: string]: HTMLAudioElement } = {};
private constructor() {
// Pre-load click sounds
CLICK_SOUNDS.forEach((sound, index) => {
const audio = new Audio(sound);
audio.volume = 0.3; // Lower volume for UI sounds
this.audioElements[`click${index + 1}`] = audio;
});
}
public static getInstance(): AudioPlayer {
if (!AudioPlayer.instance) {
AudioPlayer.instance = new AudioPlayer();
}
return AudioPlayer.instance;
}
public playClickSound() {
const randomIndex = Math.floor(Math.random() * CLICK_SOUNDS.length);
const sound = this.audioElements[`click${randomIndex + 1}`];
if (sound) {
// Create a clone to allow overlapping sounds
const clone = sound.cloneNode() as HTMLAudioElement;
clone.play();
}
}
}
export const playClickSound = () => AudioPlayer.getInstance().playClickSound();

Просмотреть файл

@ -44,12 +44,87 @@ export default {
opacity: '1',
transform: 'translateY(0)'
}
}
},
float: {
"0%, 100%": { transform: "translateY(0) translateX(0)" },
"25%": { transform: "translateY(-20px) translateX(10px)" },
"50%": { transform: "translateY(-35px) translateX(-10px)" },
"75%": { transform: "translateY(-20px) translateX(8px)" },
},
'month-transition': {
'0%': {
opacity: '0',
transform: 'scale(0.9)'
},
'20%': {
opacity: '1',
transform: 'scale(1)'
},
'80%': {
opacity: '1',
transform: 'scale(1)'
},
'100%': {
opacity: '0',
transform: 'scale(1.1)'
}
},
'typewriter': {
'from': { width: '0' },
'to': { width: '100%' }
},
'blink': {
'50%': { borderColor: 'transparent' }
},
'slide-in-left': {
'0%': { transform: 'translateX(-100%)' },
'100%': { transform: 'translateX(0)' }
},
'slide-in-right': {
'0%': { transform: 'translateX(100%)' },
'100%': { transform: 'translateX(0)' }
},
'digital-rain': {
'0%': { transform: 'translateY(-100%)', opacity: '0' },
'50%': { opacity: '1' },
'100%': { transform: 'translateY(100%)', opacity: '0' }
},
'text-glitch': {
'0%': { transform: 'translate(0)' },
'20%': { transform: 'translate(-2px, 2px)' },
'40%': { transform: 'translate(2px, -2px)' },
'60%': { transform: 'translate(-2px, -2px)' },
'80%': { transform: 'translate(2px, 2px)' },
'100%': { transform: 'translate(0)' }
},
'number-cycle': {
'0%': { transform: 'translateY(100%)', opacity: '0' },
'20%': { transform: 'translateY(0)', opacity: '1' },
'80%': { transform: 'translateY(0)', opacity: '1' },
'100%': { transform: 'translateY(-100%)', opacity: '0' }
},
'transition-container': {
'0%': { opacity: '0' },
'33%': { opacity: '1' },
'66%': { opacity: '1' },
'100%': { opacity: '0' }
},
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
'fade-in': 'fade-in 1s ease-out'
'fade-in': 'fade-in 1s ease-out',
'float': 'float 20s ease-in-out infinite',
'pulse-slow': 'pulse 4s ease-in-out infinite',
'month-transition': 'month-transition 3s ease-in-out forwards',
'typewriter': 'typewriter 2s steps(20) forwards',
'cursor-blink': 'blink 1s infinite',
'slide-left': 'slide-in-left 1.5s ease-out',
'slide-right': 'slide-in-right 1.5s ease-out',
'rain': 'digital-rain 2s linear infinite',
'glitch': 'text-glitch 0.5s ease infinite',
'cycle': 'number-cycle 0.5s ease-in-out',
'transition-container': 'transition-container 3s ease-in-out forwards',
},
colors: {
border: 'hsl(var(--border))',
@ -100,7 +175,10 @@ export default {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
}
},
backgroundImage: {
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
},
}
},
plugins: [require("tailwindcss-animate")],

Просмотреть файл

@ -6,8 +6,12 @@ import { componentTagger } from "lovable-tagger";
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
server: {
host: "::",
port: 8080,
port: 3000,
host: true
},
preview: {
port: 3000,
host: true
},
plugins: [
react(),