зеркало из
https://github.com/kodackx/disinformation-quest.git
synced 2025-10-28 20:34:15 +02:00
second version
Этот коммит содержится в:
родитель
2eb487f048
Коммит
f9f1732b78
28
README.md
28
README.md
@ -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/ElevenLabs_2024-12-06T01_53_04_Jessica Anne Bogart - Character and Animation_pvc_s42_sb99_se8_b_m2.mp3
Обычный файл
Двоичные данные
public/audio/ElevenLabs_2024-12-06T01_53_04_Jessica Anne Bogart - Character and Animation_pvc_s42_sb99_se8_b_m2.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/agent-torres-april.mp3
Обычный файл
Двоичные данные
public/audio/agent-torres-april.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/click1.mp3
Обычный файл
Двоичные данные
public/audio/click1.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/click2.mp3
Обычный файл
Двоичные данные
public/audio/click2.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/dr-chen-january.mp3
Обычный файл
Двоичные данные
public/audio/dr-chen-january.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/dr-webb-february.mp3
Обычный файл
Двоичные данные
public/audio/dr-webb-february.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/mixkit-modern-technology-select-3124.wav
Обычный файл
Двоичные данные
public/audio/mixkit-modern-technology-select-3124.wav
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/mixkit-retro-arcade-casino-notification-211.wav
Обычный файл
Двоичные данные
public/audio/mixkit-retro-arcade-casino-notification-211.wav
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/mixkit-sci-fi-click-900.wav
Обычный файл
Двоичные данные
public/audio/mixkit-sci-fi-click-900.wav
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/audio/prof-morrison-march.mp3
Обычный файл
Двоичные данные
public/audio/prof-morrison-march.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/pixabay-suspense-265381.mp3
Обычный файл
Двоичные данные
public/pixabay-suspense-265381.mp3
Обычный файл
Двоичный файл не отображается.
Двоичные данные
public/tension-background.mp3
Обычный файл
Двоичные данные
public/tension-background.mp3
Обычный файл
Двоичный файл не отображается.
53
src/components/GameBackground.tsx
Обычный файл
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
Обычный файл
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",
|
||||
},
|
||||
},
|
||||
|
||||
1090
src/pages/Index.tsx
1090
src/pages/Index.tsx
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
37
src/utils/audio.ts
Обычный файл
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(),
|
||||
|
||||
Загрузка…
x
Ссылка в новой задаче
Block a user