diff --git a/src/App.tsx b/src/App.tsx index 3629e06..69eeb5f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,13 +4,14 @@ import Case1Desktop from './cases/Case1Desktop'; import Case2Desktop from './cases/Case2Desktop'; import Case3Desktop from './cases/Case3Desktop'; import Case4Desktop from './cases/Case4Desktop'; +import Case5Desktop from './cases/Case5Desktop'; import ChatterboxTTS from './components/deepfake/ChatterboxTTS'; import MyQuize from './components/MyQuize'; import CyberSecurityArticle from './components/CyberSecurityArticle'; export type WallpaperType = 'xp' | 'win7' | 'win10'; -type OverlayType = 'case1' | 'case2' | 'case3' | 'case4' | 'deepfake' | 'quiz' | 'wiki' | null; +type OverlayType = 'case1' | 'case2' | 'case3' | 'case4' | 'case5' | 'deepfake' | 'quiz' | 'wiki' | null; const App: React.FC = () => { const [overlay, setOverlay] = useState(null); @@ -23,6 +24,7 @@ const App: React.FC = () => { 2: 'case2', 3: 'case3', 4: 'case4', + 5: 'case5', 'deepfake': 'deepfake', }; setTimeout(() => setOverlay(map[level] ?? null), 1200); @@ -56,6 +58,7 @@ const App: React.FC = () => { {overlay === 'case2' && } {overlay === 'case3' && } {overlay === 'case4' && } + {overlay === 'case5' && } {overlay === 'deepfake' && } {overlay === 'quiz' && } {overlay === 'wiki' && } diff --git a/src/cases/Case3Desktop.tsx b/src/cases/Case3Desktop.tsx index e2c50ac..bebe6ff 100644 --- a/src/cases/Case3Desktop.tsx +++ b/src/cases/Case3Desktop.tsx @@ -1,19 +1,456 @@ import React, { useState } from 'react'; import type { WallpaperType } from '../App'; -import MainApp from '../MainApp'; -// import './Case3Desktop.css'; interface Case3DesktopProps { onComplete: (type: WallpaperType) => void; } +type Page = + | 'home' + | 'mail-inbox' + | 'mail-real' + | 'mail-phishing' + | 'fake-gosuslugi' + | 'gosuslugi'; + +const PAGE_URL: Record = { + 'home': { url: 'yandex.ru', secure: true }, + 'mail-inbox': { url: 'mail.yandex.ru', secure: true }, + 'mail-real': { url: 'mail.yandex.ru', secure: true }, + 'mail-phishing': { url: 'mail.yandex.ru', secure: true }, + 'fake-gosuslugi': { url: 'g0suslugi-confirm.ru/login', secure: false }, + 'gosuslugi': { url: 'gosuslugi.ru', secure: true }, +}; + const Case3Desktop: React.FC = ({ onComplete }) => { + const [page, setPage] = useState('home'); + const [login, setLogin] = useState(''); + const [password, setPassword] = useState(''); + const [modal, setModal] = useState<'stolen' | 'success' | null>(null); + + const { url, secure } = PAGE_URL[page]; + + const goTo = (p: Page) => { setPage(p); setLogin(''); setPassword(''); }; return ( -
- +
+ {/* Браузер */} +
+ {/* Хром */} +
+ + +
+ {secure ? '🔒' : '⚠'} + {url} +
+
+ + {/* Закладки */} +
+ + +
+ + {/* Контент */} +
+ {page === 'home' && } + {page === 'mail-inbox' && } + {page === 'mail-real' && goTo('mail-inbox')} onGosuslugi={() => goTo('gosuslugi')} />} + {page === 'mail-phishing' && goTo('mail-inbox')} onLink={() => goTo('fake-gosuslugi')} />} + {page === 'fake-gosuslugi' && ( + setModal('stolen')} + /> + )} + {page === 'gosuslugi' && ( + setModal('success')} + /> + )} +
+
+ + {/* Модалки */} + {modal === 'stolen' && ( +
+
+
💀
+
Аккаунт украден!
+
+ Вы ввели логин и пароль на фишинговом сайте.
+ Домен g0suslugi-confirm.ru — подделка под госуслуги.
+ Буква o заменена на цифру 0.

+ Злоумышленник получил ваши данные и вошёл в ваш аккаунт. +
+
+ 💡 Правило: никогда не переходите по ссылкам из писем. Открывайте госуслуги только из закладок. +
+ +
+
+ )} + + {modal === 'success' && ( +
+
+
🛡️
+
Всё верно!
+
+ Вы открыли официальный сайт госуслуг напрямую из закладок.
+ Домен gosuslugi.ru — настоящий, соединение защищено HTTPS.

+ Ваши данные в безопасности. +
+ +
+
+ )}
); }; +// ── Страницы ───────────────────────────────────────── + +const HomePage: React.FC<{ onGo: (p: Page) => void }> = ({ onGo }) => ( +
+
Яндекс
+
Используйте закладки выше или откройте почту для проверки письма
+
+ + +
+
+); + +const MailInbox: React.FC<{ onOpen: (p: Page) => void }> = ({ onOpen }) => ( +
+
Входящие 2 новых
+ {/* Фишинговое письмо — выглядит срочно, идёт первым */} +
onOpen('mail-phishing')}> +
+ security@g0suslugi-confirm.ru + 10:47 +
+
⚠ Требуется подтверждение аккаунта
+
Ваш аккаунт будет заблокирован. Подтвердите данные в течение 24 часов...
+
+ {/* Настоящее письмо */} +
onOpen('mail-real')}> +
+ noreply@gosuslugi.ru + 09:12 +
+
Ваша заявка №2847 отклонена
+
Заявка на получение справки была отклонена в связи с неполным пакетом...
+
+
+); + +const EmailReal: React.FC<{ onBack: () => void; onGosuslugi: () => void }> = ({ onBack, onGosuslugi }) => ( +
+ +
+ От: noreply@gosuslugi.ru +
+
Ваша заявка №2847 отклонена
+
+

Уважаемый пользователь,

+

Ваша заявка на получение справки об отсутствии задолженностей (№2847) была отклонена.

+

Причина: неполный пакет документов. Отсутствует копия паспорта.

+

Для повторной подачи заявки войдите на портал Госуслуги.

+

Это автоматическое сообщение, не отвечайте на него.

+
+
+ Нужно войти на Госуслуги для повторной подачи + +
+
+); + +const EmailPhishing: React.FC<{ onBack: () => void; onLink: () => void }> = ({ onBack, onLink }) => ( +
+ +
+ От: security@g0suslugi-confirm.ru + ⚠ Подозрительный отправитель +
+
⚠ Требуется срочное подтверждение аккаунта
+
+

Уважаемый пользователь,

+

Мы зафиксировали подозрительную активность в вашем аккаунте.

+

В целях безопасности ваш аккаунт будет заблокирован через 24 часа, если вы не подтвердите личность.

+

Нажмите кнопку ниже для подтверждения:

+ +

+ © Портал государственных услуг. Если вы не запрашивали это письмо — проигнорируйте его. +

+
+
+); + +const FakeGosuslugi: React.FC<{ + login: string; password: string; + setLogin: (v: string) => void; setPassword: (v: string) => void; + onSubmit: () => void; +}> = ({ login, password, setLogin, setPassword, onSubmit }) => ( +
+
⚠ HTTP — незащищённое соединение
+
+ 🏛 + Госуслуги +
+
Подтверждение личности
+
+ setLogin(e.target.value)} /> + setPassword(e.target.value)} /> + +
+
+ g0suslugi-confirm.ru +
+
+); + +const RealGosuslugi: React.FC<{ + login: string; password: string; + setLogin: (v: string) => void; setPassword: (v: string) => void; + onSubmit: () => void; +}> = ({ login, password, setLogin, setPassword, onSubmit }) => ( +
+
🔒 Безопасное соединение · gosuslugi.ru
+
+ 🏛 + Госуслуги +
+
Войдите в личный кабинет
+
+ setLogin(e.target.value)} /> + setPassword(e.target.value)} /> + +
+
+ gosuslugi.ru · Официальный портал +
+
+); + +// ── Стили ───────────────────────────────────────────── + +const s: Record = { + root: { + minHeight: '100vh', + background: '#0a0a0a', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + padding: '24px 16px', + fontFamily: "'Share Tech Mono', monospace", + }, + browser: { + width: '100%', + maxWidth: 800, + background: '#0d0d22', + border: '1px solid rgba(0,255,255,0.2)', + borderRadius: 10, + overflow: 'hidden', + boxShadow: '0 0 40px rgba(0,255,255,0.08)', + }, + chrome: { + background: '#080818', + borderBottom: '1px solid rgba(0,255,255,0.15)', + padding: '10px 12px', + display: 'flex', + alignItems: 'center', + gap: 8, + }, + navBtn: { + background: 'transparent', + border: '1px solid rgba(255,255,255,0.1)', + color: '#888', + borderRadius: 4, + padding: '4px 8px', + cursor: 'pointer', + fontSize: 14, + }, + urlBar: { + flex: 1, + background: '#0a0a1a', + border: '1px solid rgba(0,255,255,0.15)', + borderRadius: 4, + padding: '6px 12px', + display: 'flex', + alignItems: 'center', + gap: 8, + fontSize: 13, + }, + httpsIcon: { color: '#00FF41', fontSize: 14 }, + httpIcon: { color: '#f5a623', fontSize: 14 }, + urlText: { flex: 1 }, + bookmarks: { + background: '#060612', + borderBottom: '1px solid rgba(0,255,255,0.08)', + padding: '6px 12px', + display: 'flex', + gap: 8, + }, + bookmark: { + background: 'transparent', + border: '1px solid rgba(0,255,255,0.15)', + color: '#888', + borderRadius: 4, + padding: '3px 10px', + cursor: 'pointer', + fontSize: 12, + fontFamily: "'Share Tech Mono', monospace", + }, + content: { minHeight: 420 }, + + // Home + homePage: { + display: 'flex', flexDirection: 'column', alignItems: 'center', + justifyContent: 'center', padding: 40, gap: 20, + }, + yandexLogo: { + fontSize: 48, fontWeight: 900, color: '#FF0040', + fontFamily: "'Orbitron', monospace", letterSpacing: 2, + }, + homeHint: { color: '#555', fontSize: 13, textAlign: 'center' }, + homeIcons: { display: 'flex', gap: 32, marginTop: 16 }, + homeIcon: { + background: 'rgba(0,255,255,0.04)', border: '1px solid rgba(0,255,255,0.15)', + borderRadius: 10, padding: '16px 24px', cursor: 'pointer', + display: 'flex', flexDirection: 'column', alignItems: 'center', + gap: 8, color: '#aaa', fontSize: 13, fontFamily: "'Share Tech Mono', monospace", + }, + + // Mail + mailPage: { padding: 0 }, + mailHeader: { + padding: '14px 20px', borderBottom: '1px solid rgba(0,255,255,0.1)', + color: '#ccc', fontFamily: "'Orbitron', monospace", fontSize: 14, + display: 'flex', alignItems: 'center', gap: 10, + }, + emailRow: { + padding: '14px 20px', borderBottom: '1px solid rgba(255,255,255,0.05)', + cursor: 'pointer', transition: 'background 0.15s', + }, + emailFrom: { display: 'flex', justifyContent: 'space-between', marginBottom: 4 }, + emailSender: { color: '#aaa', fontSize: 13, fontWeight: 'bold' }, + emailTime: { color: '#555', fontSize: 12 }, + emailSubject: { color: '#ddd', fontSize: 14, marginBottom: 3 }, + emailPreview: { color: '#555', fontSize: 12 }, + + // Email view + emailPage: { padding: 20 }, + backLink: { + background: 'transparent', border: 'none', color: '#00FFFF', + cursor: 'pointer', fontSize: 13, padding: 0, marginBottom: 16, + fontFamily: "'Share Tech Mono', monospace", + }, + emailFullFrom: { fontSize: 13, color: '#888', marginBottom: 6, display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }, + emailFullSubject: { color: '#ddd', fontSize: 16, fontWeight: 'bold', marginBottom: 16, fontFamily: "'Orbitron', monospace" }, + emailBody: { color: '#aaa', fontSize: 14, lineHeight: 1.8, marginBottom: 20 }, + suspiciousBadge: { + background: 'rgba(245,166,35,0.12)', border: '1px solid #f5a623', + color: '#f5a623', fontSize: 11, borderRadius: 4, padding: '2px 8px', + }, + phishingLink: { + background: 'rgba(0,120,255,0.15)', border: '1px solid #0078ff', + color: '#4da6ff', borderRadius: 6, padding: '10px 20px', + cursor: 'pointer', fontSize: 14, fontFamily: "'Share Tech Mono', monospace", + display: 'block', marginTop: 8, + }, + emailActions: { + borderTop: '1px solid rgba(0,255,255,0.1)', + paddingTop: 16, display: 'flex', flexDirection: 'column', gap: 10, + }, + actionBtn: { + background: '#00FFFF', border: 'none', borderRadius: 6, + padding: '10px 20px', color: '#000', cursor: 'pointer', + fontSize: 13, fontFamily: "'Orbitron', monospace", fontWeight: 700, + alignSelf: 'flex-start', + }, + + // Gosuslugi pages + gosPage: { padding: 32, display: 'flex', flexDirection: 'column', alignItems: 'center' }, + fakeWarning: { + background: 'rgba(245,166,35,0.12)', border: '1px solid #f5a623', + color: '#f5a623', borderRadius: 6, padding: '8px 16px', + fontSize: 12, marginBottom: 24, width: '100%', textAlign: 'center', + }, + realSafe: { + background: 'rgba(0,255,65,0.08)', border: '1px solid #00FF41', + color: '#00FF41', borderRadius: 6, padding: '8px 16px', + fontSize: 12, marginBottom: 24, width: '100%', textAlign: 'center', + }, + gosHeader: { display: 'flex', alignItems: 'center', gap: 12, marginBottom: 6 }, + gosTitle: { color: '#00FFFF', fontFamily: "'Orbitron', monospace", fontSize: 22, fontWeight: 700 }, + gosSubtitle: { color: '#888', fontSize: 13, marginBottom: 24 }, + loginForm: { display: 'flex', flexDirection: 'column', gap: 12, width: '100%', maxWidth: 320 }, + input: { + background: '#0a0a1a', border: '1px solid rgba(0,255,255,0.2)', + borderRadius: 6, padding: '10px 14px', color: '#ccc', + fontSize: 14, fontFamily: "'Share Tech Mono', monospace", + outline: 'none', + }, + loginBtn: { + padding: '12px', borderRadius: 6, border: 'none', + fontFamily: "'Orbitron', monospace", fontSize: 14, fontWeight: 700, + cursor: 'pointer', transition: 'opacity 0.2s', + }, + + // Modals + modalOverlay: { + position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.8)', + display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 200, + }, + modal: { + background: '#0d0d22', border: '2px solid', + borderRadius: 12, padding: '32px 28px', maxWidth: 440, width: '90%', + textAlign: 'center', boxShadow: '0 0 40px rgba(0,0,0,0.5)', + }, + modalIcon: { fontSize: 48, marginBottom: 12 }, + modalTitle: { fontFamily: "'Orbitron', monospace", fontSize: 18, fontWeight: 700, marginBottom: 12 }, + modalText: { color: '#aaa', fontSize: 14, lineHeight: 1.7, marginBottom: 16 }, + modalHint: { + background: 'rgba(0,255,255,0.06)', border: '1px solid rgba(0,255,255,0.2)', + borderRadius: 6, padding: '10px 14px', color: '#888', fontSize: 13, + marginBottom: 20, textAlign: 'left', + }, + modalBtn: { + padding: '12px 28px', borderRadius: 6, cursor: 'pointer', + fontFamily: "'Orbitron', monospace", fontSize: 13, fontWeight: 700, + }, +}; + export default Case3Desktop; diff --git a/src/cases/Case5Desktop.tsx b/src/cases/Case5Desktop.tsx new file mode 100644 index 0000000..ff9338f --- /dev/null +++ b/src/cases/Case5Desktop.tsx @@ -0,0 +1,1138 @@ +import React, { useState } from 'react'; +import type { WallpaperType } from '../App'; + +interface Case5DesktopProps { + onComplete: (type: WallpaperType) => void; +} + +interface Site { + id: number; + name: string; + domain: string; + https: boolean; + isLegit: boolean; + description: string; + price: number; + productName: string; + paymentProcessor: string | null; // null = прямая форма (скиммер) + skimmerHint: string | null; + adLabel?: boolean; +} + +const SITES: Site[] = [ + { + id: 1, + name: 'KleyMaster — магазин клея', + domain: 'kley-master.ru', + https: true, + isLegit: true, + description: 'Широкий ассортимент клея: ПВА, момент, эпоксидный. Доставка по России.', + price: 149, + productName: 'Клей ПВА "Универсал" 250мл', + paymentProcessor: 'Тинькофф', + skimmerHint: null, + }, + { + id: 2, + name: 'Kley-Online — купить клей дёшево', + domain: 'kley-online.shop', + https: false, + isLegit: false, + adLabel: true, + description: 'Клей ПВА, суперклей, момент. Скидки до 70%! Доставка 1 день.', + price: 99, + productName: 'Клей ПВА 250мл', + paymentProcessor: null, + skimmerHint: 'HTTP-соединение: данные карты передаются в открытом виде', + }, + { + id: 3, + name: 'SuperKley Discount — акции и скидки', + domain: 'superkley-discount.ru', + https: false, + isLegit: false, + adLabel: true, + description: 'Суперклей, ПВА, эпоксидный. Оптовые цены. Акция: -50% на всё!', + price: 75, + productName: 'ПВА клей универсальный', + paymentProcessor: null, + skimmerHint: 'Домен зарегистрирован 3 дня назад, нет контактов и юридических данных', + }, + { + id: 4, + name: 'HobbyTrade — товары для творчества', + domain: 'hobbytrade-shop.ru', + https: true, + isLegit: true, + description: 'Материалы для рукоделия, клей, краски. Более 15 лет на рынке.', + price: 162, + productName: 'Клей ПВА "Универсал" 250мл', + paymentProcessor: 'СберПей', + skimmerHint: null, + }, + { + id: 5, + name: 'KleyCheap — дешевле не бывает', + domain: 'kleycheap.xyz', + https: false, + isLegit: false, + adLabel: true, + description: 'Клей по ценам производителя. Без наценки! Только сегодня -60%.', + price: 59, + productName: 'Клей ПВА 250мл АКЦИЯ', + paymentProcessor: null, + skimmerHint: 'Домен в зоне .xyz — часто используется мошенниками', + }, + { + id: 6, + name: 'Kley-Market Online — каталог клея', + domain: 'kley-market-online.ru', + https: true, + isLegit: false, + description: 'Большой каталог клея. Быстрая доставка. Безопасная оплата.', + price: 139, + productName: 'Клей ПВА 250мл', + paymentProcessor: null, + skimmerHint: 'Форма оплаты не перенаправляет на банк — данные карты попадают прямо на сайт', + }, + { + id: 7, + name: 'BestKley — выгодные покупки', + domain: 'best-kley.site', + https: false, + isLegit: false, + adLabel: true, + description: 'Лучший клей по лучшим ценам. Гарантия качества. Отзывы покупателей.', + price: 89, + productName: 'Клей ПВА BEST 250мл', + paymentProcessor: null, + skimmerHint: 'Домен .site и отсутствие HTTPS — типичные признаки фишингового магазина', + }, + { + id: 8, + name: 'Kley-Opt — оптовые цены', + domain: 'kley-opt24.ru', + https: true, + isLegit: false, + description: 'Клей оптом и в розницу. Цены от производителя. Доставка 2-3 дня.', + price: 119, + productName: 'Клей ПВА универсальный', + paymentProcessor: null, + skimmerHint: 'Скопированный дизайн чужого магазина, платёжная форма ведёт на сторонний сервер', + }, + { + id: 9, + name: 'MegaKley24 — акционные предложения', + domain: 'megakley24.ru', + https: true, + isLegit: false, + adLabel: true, + description: 'Клей ПВА, момент, суперклей. 24/7. Карты Visa/MasterCard. Быстро.', + price: 109, + productName: 'Клей ПВА 250мл выгодно', + paymentProcessor: null, + skimmerHint: 'Страница оплаты загружает сторонний скрипт, перехватывающий данные карты', + }, + { + id: 10, + name: 'Kley-Sale — распродажа клея', + domain: 'kley-sale.shop', + https: false, + isLegit: false, + description: 'Распродажа! Клей ПВА, эпоксидный, момент. Только сегодня!', + price: 49, + productName: 'Клей ПВА SALE', + paymentProcessor: null, + skimmerHint: 'Сайт создан вчера, нет ИНН/ОГРН, телефон не существует', + }, +]; + +type PageType = 'search' | 'product' | 'payment' | null; + +const Case5Desktop: React.FC = ({ onComplete }) => { + const [searchQuery, setSearchQuery] = useState('купить клей пва 250мл'); + const [searched, setSearched] = useState(false); + const [selectedSite, setSelectedSite] = useState(null); + const [page, setPage] = useState(null); + const [cardNum, setCardNum] = useState(''); + const [cardExp, setCardExp] = useState(''); + const [cardCvv, setCardCvv] = useState(''); + const [modal, setModal] = useState<'skimmer' | 'success' | null>(null); + + const currentUrl = (() => { + if (!selectedSite) return 'ya.ru'; + if (page === 'product') return `${selectedSite.domain}/catalog/kley-pva`; + if (page === 'payment') return `${selectedSite.domain}/checkout/payment`; + return 'ya.ru'; + })(); + + const isSecure = (() => { + if (!selectedSite) return true; + return selectedSite.https; + })(); + + const goSearch = () => setSearched(true); + const openSite = (site: Site) => { setSelectedSite(site); setPage('product'); }; + const goToPayment = () => setPage('payment'); + + const handlePay = () => { + if (!selectedSite) return; + if (selectedSite.isLegit) { + setModal('success'); + } else { + setModal('skimmer'); + } + }; + + const resetToSearch = () => { + setModal(null); + setSelectedSite(null); + setPage(null); + setCardNum(''); + setCardExp(''); + setCardCvv(''); + }; + + return ( +
+ {/* Легенда */} +
+

+ Вам нужно купить клей ПВА для ремонта. Вы открываете Яндекс и ищете товар в интернете. +
+ Задача: найти надёжный магазин и безопасно оплатить покупку. +

+
+ + {/* Браузер */} +
+ {/* Хром браузера */} +
+ {selectedSite && ( + + )} +
+ {isSecure ? '🔒' : '⚠'} + {currentUrl} + {!isSecure && Небезопасно} +
+
+ + {/* Контент */} +
+ + {/* === ЯНДЕКС ПОИСК === */} + {!searched && !selectedSite && ( +
+
+ Я + ндекс +
+
+ setSearchQuery(e.target.value)} + onKeyDown={e => e.key === 'Enter' && goSearch()} + placeholder="Найти в интернете" + /> + +
+
+ )} + + {/* === РЕЗУЛЬТАТЫ ПОИСКА === */} + {searched && !selectedSite && ( +
+
+
+ Я + setSearchQuery(e.target.value)} + onKeyDown={e => e.key === 'Enter' && goSearch()} + /> + +
+
Нашлось 10 результатов
+
+ +
+ {SITES.map((site) => ( +
openSite(site)}> + {site.adLabel && Реклама} +
{site.name}
+
+ {site.https ? '🔒' : '⚠'} {site.domain} +
+
{site.description}
+
от {site.price} ₽
+
+ ))} +
+
+ )} + + {/* === СТРАНИЦА ТОВАРА === */} + {selectedSite && page === 'product' && ( +
+
+ {selectedSite.name} + {!selectedSite.https && ( + ⚠ HTTP — небезопасный сайт + )} +
+ +
+
+ 🧴 +
+
+
{selectedSite.productName}
+
{selectedSite.price} ₽
+
+ Объём: 250 мл · В наличии · Доставка 2–5 дней +
+ +
+
+ + {/* Подозрительные признаки */} + {!selectedSite.isLegit && ( +
+
💡 Обратите внимание на признаки сайта:
+
    + {!selectedSite.https &&
  • ⚠ Сайт не использует HTTPS
  • } + {selectedSite.domain.includes('.xyz') &&
  • ⚠ Нестандартный домен (.xyz)
  • } + {selectedSite.domain.includes('.shop') &&
  • ⚠ Нестандартный домен (.shop)
  • } + {selectedSite.domain.includes('.site') &&
  • ⚠ Нестандартный домен (.site)
  • } + {selectedSite.adLabel &&
  • ℹ Рекламная ссылка в поиске
  • } +
  • ℹ Нет раздела «О компании», нет ИНН / ОГРН
  • +
+
+ )} + {selectedSite.isLegit && ( +
+
✅ Признаки надёжного магазина:
+
    +
  • ✅ HTTPS — соединение зашифровано
  • +
  • ✅ Известный домен .ru
  • +
  • ✅ Есть раздел «О нас» с ИНН и ОГРН
  • +
  • ✅ Оплата через проверенную платёжную систему
  • +
+
+ )} +
+ )} + + {/* === СТРАНИЦА ОПЛАТЫ === */} + {selectedSite && page === 'payment' && ( +
+
Оформление заказа
+ + {/* Сводка заказа */} +
+
+ Товар: + {selectedSite.productName} +
+
+ Сумма: + + {selectedSite.price} ₽ + +
+
+ + {/* Форма оплаты — легитимная */} + {selectedSite.isLegit ? ( +
+
+ 🏦 + Оплата через {selectedSite.paymentProcessor} + 🔒 Защищено +
+

+ Вы будете перенаправлены на защищённую страницу банка. + Магазин не получает данные вашей карты. +

+
+ + setCardNum(e.target.value)} + maxLength={19} + /> +
+
+ + setCardExp(e.target.value)} + maxLength={5} + /> +
+
+ + setCardCvv(e.target.value)} + maxLength={3} + type="password" + /> +
+
+
+ +
+ ) : ( + /* Форма оплаты — скиммер */ +
+
+ 🔒 + Безопасная оплата картой + VISA + MC +
+
+ + setCardNum(e.target.value)} + maxLength={19} + /> +
+
+ + setCardExp(e.target.value)} + maxLength={5} + /> +
+
+ + setCardCvv(e.target.value)} + maxLength={3} + type="password" + /> +
+
+
+ +
+ )} +
+ )} +
+
+ + {/* === МОДАЛ: СКИММЕР === */} + {modal === 'skimmer' && selectedSite && ( +
+
+
💀
+
Скиммер! Данные карты похищены
+
+ Вы ввели данные карты на сайте {selectedSite.domain}, + который использует веб-скиммер — вредоносный скрипт, перехватывающий + платёжные данные прямо на странице оплаты. +
+ +
+
Что такое скимминг?
+
+ Скиммер — код, встроенный в страницу оплаты. Пока вы вводите номер карты, + он тайно копирует данные и отправляет злоумышленнику. Внешне страница + выглядит как обычная форма оплаты. +
+
+ +
+
Почему этот сайт подозрителен:
+
{selectedSite.skimmerHint}
+
+ +
+
Как защититься:
+
    +
  • Платите только на известных площадках (Ozon, Wildberries, DNS и т.п.)
  • +
  • Ищите перенаправление на страницу банка (СберПей, Тинькофф и др.)
  • +
  • Проверяйте HTTPS и домен перед вводом карты
  • +
  • Используйте виртуальную карту с лимитом для онлайн-покупок
  • +
+
+ + +
+
+ )} + + {/* === МОДАЛ: УСПЕХ === */} + {modal === 'success' && selectedSite && ( +
+
+
+
Покупка совершена безопасно!
+
+ Оплата прошла через {selectedSite.paymentProcessor}. + Магазин {selectedSite.domain} не получил данные вашей карты — + они были переданы напрямую банку по зашифрованному соединению. +
+
+
+ Товар: + {selectedSite.productName} +
+
+ Сумма: + {selectedSite.price} ₽ +
+
+ Статус: + Оплачено +
+
+ +
+
+ )} +
+ ); +}; + +const s: Record = { + root: { + minHeight: '100vh', + background: 'linear-gradient(135deg, #0a0a14 0%, #0d1117 60%, #0a1400 100%)', + color: '#ccc', + fontFamily: "'Share Tech Mono', monospace", + padding: '0 0 40px', + }, + story: { + maxWidth: 760, + margin: '24px auto 0', + padding: '14px 24px', + background: 'rgba(0,255,255,0.04)', + border: '1px solid rgba(0,255,255,0.15)', + borderRadius: 8, + fontSize: 14, + lineHeight: 1.7, + color: '#aaa', + textAlign: 'center', + }, + browser: { + maxWidth: 860, + margin: '24px auto 0', + border: '1px solid rgba(0,255,255,0.2)', + borderRadius: 10, + overflow: 'hidden', + boxShadow: '0 0 30px rgba(0,255,255,0.06)', + }, + chrome: { + background: '#080818', + borderBottom: '1px solid rgba(0,255,255,0.15)', + padding: '8px 12px', + display: 'flex', + alignItems: 'center', + gap: 8, + }, + navBtn: { + background: 'rgba(255,255,255,0.06)', + border: '1px solid rgba(255,255,255,0.1)', + color: '#888', + borderRadius: 4, + padding: '4px 10px', + cursor: 'pointer', + fontSize: 14, + fontFamily: "'Share Tech Mono', monospace", + }, + urlBar: { + flex: 1, + background: '#0a0a1a', + border: '1px solid rgba(0,255,255,0.2)', + borderRadius: 4, + padding: '5px 12px', + fontSize: 13, + display: 'flex', + alignItems: 'center', + gap: 8, + }, + httpsIcon: { color: '#00FF41', fontSize: 13 }, + httpIcon: { color: '#f5a623', fontSize: 13 }, + urlText: { flex: 1 }, + httpWarnText: { color: '#f5a623', fontSize: 11, marginLeft: 4 }, + content: { + background: '#0d0d0d', + minHeight: 480, + }, + + /* Яндекс главная */ + yandexHome: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + paddingTop: 80, + paddingBottom: 60, + gap: 28, + }, + yandexLogo: { + fontSize: 52, + fontWeight: 700, + lineHeight: 1, + }, + yandexY: { + color: '#FF0040', + fontFamily: 'Georgia, serif', + }, + yandexNdex: { + color: '#eee', + fontFamily: 'Georgia, serif', + }, + searchBox: { + display: 'flex', + width: '100%', + maxWidth: 560, + gap: 0, + }, + searchInput: { + flex: 1, + padding: '12px 16px', + background: '#1a1a2e', + border: '1px solid rgba(0,255,255,0.25)', + borderRight: 'none', + borderRadius: '6px 0 0 6px', + color: '#eee', + fontSize: 15, + fontFamily: "'Share Tech Mono', monospace", + outline: 'none', + }, + searchBtn: { + padding: '12px 24px', + background: '#FF0040', + border: 'none', + borderRadius: '0 6px 6px 0', + color: '#fff', + fontFamily: "'Orbitron', monospace", + fontSize: 13, + fontWeight: 700, + cursor: 'pointer', + }, + + /* Результаты поиска */ + searchResults: { + padding: '0 0 24px', + }, + searchResultsHeader: { + background: '#080818', + borderBottom: '1px solid rgba(0,255,255,0.1)', + padding: '10px 16px', + display: 'flex', + alignItems: 'center', + gap: 16, + flexWrap: 'wrap', + }, + searchBoxSmall: { + display: 'flex', + alignItems: 'center', + flex: 1, + maxWidth: 400, + background: '#0d0d22', + border: '1px solid rgba(0,255,255,0.2)', + borderRadius: 6, + overflow: 'hidden', + }, + yandexSmall: { + color: '#FF0040', + fontFamily: 'Georgia, serif', + fontSize: 18, + fontWeight: 700, + padding: '0 8px', + }, + searchInputSmall: { + flex: 1, + background: 'transparent', + border: 'none', + color: '#eee', + fontSize: 13, + fontFamily: "'Share Tech Mono', monospace", + padding: '8px 4px', + outline: 'none', + }, + searchBtnSmall: { + background: 'transparent', + border: 'none', + color: '#888', + cursor: 'pointer', + padding: '8px 12px', + fontSize: 14, + }, + resultCount: { + color: '#555', + fontSize: 12, + }, + resultsList: { + padding: '8px 20px', + display: 'flex', + flexDirection: 'column', + gap: 2, + }, + resultItem: { + padding: '14px 16px', + borderRadius: 6, + cursor: 'pointer', + transition: 'background 0.15s', + borderBottom: '1px solid rgba(255,255,255,0.04)', + }, + adBadge: { + display: 'inline-block', + background: 'rgba(245,166,35,0.15)', + border: '1px solid rgba(245,166,35,0.4)', + color: '#f5a623', + fontSize: 10, + padding: '1px 6px', + borderRadius: 3, + marginBottom: 4, + fontFamily: "'Share Tech Mono', monospace", + }, + resultName: { + color: '#5b9bd5', + fontSize: 15, + marginBottom: 2, + }, + resultDomain: { + fontSize: 12, + marginBottom: 4, + }, + resultDesc: { + color: '#777', + fontSize: 13, + lineHeight: 1.5, + }, + resultPrice: { + color: '#00FF41', + fontSize: 13, + marginTop: 4, + fontFamily: "'Orbitron', monospace", + }, + + /* Страница товара */ + productPage: { + padding: 24, + }, + shopHeader: { + display: 'flex', + alignItems: 'center', + gap: 16, + marginBottom: 20, + paddingBottom: 12, + borderBottom: '1px solid rgba(255,255,255,0.06)', + }, + shopName: { + color: '#00FFFF', + fontFamily: "'Orbitron', monospace", + fontSize: 14, + fontWeight: 700, + }, + unsafeBadge: { + background: 'rgba(245,166,35,0.15)', + border: '1px solid #f5a623', + color: '#f5a623', + fontSize: 11, + padding: '3px 10px', + borderRadius: 4, + }, + productCard: { + display: 'flex', + gap: 24, + background: 'rgba(255,255,255,0.03)', + border: '1px solid rgba(255,255,255,0.08)', + borderRadius: 8, + padding: 20, + marginBottom: 20, + }, + productImage: { + width: 100, + height: 100, + background: 'rgba(255,255,255,0.05)', + borderRadius: 8, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + }, + productInfo: { + flex: 1, + }, + productTitle: { + color: '#ddd', + fontSize: 16, + marginBottom: 8, + lineHeight: 1.4, + }, + productPriceTag: { + color: '#00FF41', + fontFamily: "'Orbitron', monospace", + fontSize: 22, + fontWeight: 700, + marginBottom: 8, + }, + productDesc: { + color: '#666', + fontSize: 12, + marginBottom: 16, + }, + buyBtn: { + padding: '10px 28px', + background: '#00FFFF', + border: 'none', + borderRadius: 6, + color: '#000', + fontFamily: "'Orbitron', monospace", + fontSize: 13, + fontWeight: 700, + cursor: 'pointer', + }, + suspiciousHints: { + background: 'rgba(245,166,35,0.06)', + border: '1px solid rgba(245,166,35,0.3)', + borderRadius: 8, + padding: '14px 18px', + marginTop: 16, + }, + hintTitle: { + color: '#f5a623', + fontSize: 13, + marginBottom: 8, + fontFamily: "'Orbitron', monospace", + fontWeight: 700, + }, + legitHints: { + background: 'rgba(0,255,65,0.05)', + border: '1px solid rgba(0,255,65,0.25)', + borderRadius: 8, + padding: '14px 18px', + marginTop: 16, + }, + hintTitleGood: { + color: '#00FF41', + fontSize: 13, + marginBottom: 8, + fontFamily: "'Orbitron', monospace", + fontWeight: 700, + }, + hintList: { + margin: 0, + paddingLeft: 20, + color: '#aaa', + fontSize: 13, + lineHeight: 1.8, + }, + + /* Страница оплаты */ + paymentPage: { + padding: 24, + maxWidth: 480, + margin: '0 auto', + }, + paymentTitle: { + color: '#00FFFF', + fontFamily: "'Orbitron', monospace", + fontSize: 16, + fontWeight: 700, + marginBottom: 16, + textAlign: 'center', + }, + orderSummary: { + background: 'rgba(0,255,255,0.04)', + border: '1px solid rgba(0,255,255,0.15)', + borderRadius: 8, + padding: '12px 16px', + marginBottom: 20, + }, + orderRow: { + display: 'flex', + justifyContent: 'space-between', + padding: '4px 0', + fontSize: 13, + }, + orderLabel: { color: '#666' }, + orderValue: { color: '#ddd' }, + legitPayment: { + background: 'rgba(0,255,65,0.04)', + border: '1px solid rgba(0,255,65,0.2)', + borderRadius: 8, + padding: 20, + }, + processorBadge: { + display: 'flex', + alignItems: 'center', + gap: 10, + marginBottom: 10, + padding: '8px 14px', + background: 'rgba(0,255,65,0.08)', + borderRadius: 6, + }, + processorIcon: { fontSize: 20 }, + processorName: { color: '#00FF41', fontFamily: "'Orbitron', monospace", fontSize: 13, fontWeight: 700, flex: 1 }, + processorSecure: { color: '#00FF41', fontSize: 12 }, + processorNote: { + color: '#777', + fontSize: 12, + lineHeight: 1.6, + marginBottom: 16, + textAlign: 'center', + }, + fakePayment: { + background: 'rgba(255,255,255,0.03)', + border: '1px solid rgba(255,255,255,0.1)', + borderRadius: 8, + padding: 20, + }, + fakeSecureBadge: { + display: 'flex', + alignItems: 'center', + gap: 8, + marginBottom: 16, + color: '#888', + fontSize: 12, + }, + visaBadge: { + background: '#1a1a6e', + color: '#fff', + padding: '1px 6px', + borderRadius: 3, + fontSize: 10, + fontWeight: 700, + }, + mcBadge: { + background: '#8b0000', + color: '#fff', + padding: '1px 6px', + borderRadius: 3, + fontSize: 10, + fontWeight: 700, + }, + cardForm: { + display: 'flex', + flexDirection: 'column', + gap: 12, + marginBottom: 16, + }, + cardLabel: { + display: 'block', + color: '#666', + fontSize: 11, + marginBottom: 4, + fontFamily: "'Share Tech Mono', monospace", + }, + cardInput: { + width: '100%', + padding: '9px 12px', + background: '#0a0a1a', + border: '1px solid rgba(0,255,255,0.2)', + borderRadius: 5, + color: '#ddd', + fontSize: 14, + fontFamily: "'Share Tech Mono', monospace", + outline: 'none', + boxSizing: 'border-box', + }, + payBtn: { + width: '100%', + padding: '12px', + background: '#00FF41', + border: 'none', + borderRadius: 6, + color: '#000', + fontFamily: "'Orbitron', monospace", + fontSize: 14, + fontWeight: 700, + cursor: 'pointer', + }, + payBtnFake: { + width: '100%', + padding: '12px', + background: '#2255cc', + border: 'none', + borderRadius: 6, + color: '#fff', + fontFamily: 'Arial, sans-serif', + fontSize: 14, + fontWeight: 700, + cursor: 'pointer', + }, + + /* Модалки */ + modalOverlay: { + position: 'fixed', + inset: 0, + background: 'rgba(0,0,0,0.8)', + display: 'flex', + alignItems: 'flex-start', + justifyContent: 'center', + zIndex: 200, + overflowY: 'auto', + padding: '40px 16px', + }, + modalDanger: { + background: '#0d0d22', + border: '1px solid #FF0040', + borderRadius: 12, + padding: '28px 28px 24px', + maxWidth: 520, + width: '100%', + boxShadow: '0 0 40px rgba(255,0,64,0.25)', + textAlign: 'center', + }, + modalSuccess: { + background: '#0d0d22', + border: '1px solid #00FF41', + borderRadius: 12, + padding: '28px 28px 24px', + maxWidth: 480, + width: '100%', + boxShadow: '0 0 40px rgba(0,255,65,0.2)', + textAlign: 'center', + }, + modalIcon: { fontSize: 48, marginBottom: 12 }, + modalTitle: { + color: '#FF0040', + fontFamily: "'Orbitron', monospace", + fontSize: 16, + fontWeight: 700, + marginBottom: 12, + }, + modalText: { + color: '#aaa', + fontSize: 13, + lineHeight: 1.7, + marginBottom: 16, + }, + skimmerExplain: { + background: 'rgba(255,0,64,0.06)', + border: '1px solid rgba(255,0,64,0.25)', + borderRadius: 8, + padding: '12px 16px', + marginBottom: 12, + textAlign: 'left', + }, + skimmerExplainTitle: { + color: '#FF0040', + fontFamily: "'Orbitron', monospace", + fontSize: 12, + fontWeight: 700, + marginBottom: 6, + }, + skimmerExplainText: { + color: '#aaa', + fontSize: 13, + lineHeight: 1.6, + }, + skimmerReason: { + background: 'rgba(245,166,35,0.06)', + border: '1px solid rgba(245,166,35,0.25)', + borderRadius: 8, + padding: '12px 16px', + marginBottom: 12, + textAlign: 'left', + }, + skimmerReasonTitle: { + color: '#f5a623', + fontFamily: "'Orbitron', monospace", + fontSize: 12, + fontWeight: 700, + marginBottom: 6, + }, + skimmerReasonText: { + color: '#aaa', + fontSize: 13, + lineHeight: 1.6, + }, + safeRules: { + background: 'rgba(0,255,65,0.04)', + border: '1px solid rgba(0,255,65,0.2)', + borderRadius: 8, + padding: '12px 16px', + marginBottom: 20, + textAlign: 'left', + }, + safeRulesTitle: { + color: '#00FF41', + fontFamily: "'Orbitron', monospace", + fontSize: 12, + fontWeight: 700, + marginBottom: 8, + }, + safeRulesList: { + margin: 0, + paddingLeft: 20, + color: '#aaa', + fontSize: 13, + lineHeight: 1.8, + }, + retryBtn: { + padding: '10px 20px', + background: 'transparent', + border: '1px solid rgba(0,255,255,0.3)', + borderRadius: 6, + color: '#888', + cursor: 'pointer', + fontFamily: "'Share Tech Mono', monospace", + fontSize: 13, + }, + successDetails: { + background: 'rgba(0,255,65,0.05)', + border: '1px solid rgba(0,255,65,0.2)', + borderRadius: 8, + padding: '12px 16px', + marginBottom: 20, + textAlign: 'left', + }, + successRow: { + display: 'flex', + justifyContent: 'space-between', + padding: '4px 0', + fontSize: 13, + color: '#aaa', + }, + completeBtn: { + padding: '12px 36px', + background: '#00FF41', + border: 'none', + borderRadius: 6, + color: '#000', + fontFamily: "'Orbitron', monospace", + fontSize: 14, + fontWeight: 700, + cursor: 'pointer', + }, +}; + +export default Case5Desktop; diff --git a/src/cases/CybersecMenu.css b/src/cases/CybersecMenu.css index 3102968..c95f6f2 100644 --- a/src/cases/CybersecMenu.css +++ b/src/cases/CybersecMenu.css @@ -311,11 +311,49 @@ .csm-level-4 .csm-tooltip::after { border-left-color: var(--csm-cyan); } .csm-level-4 .csm-tooltip-title { color: var(--csm-cyan); } -.csm-deepfake:hover .csm-hexagon-bg { stroke: #FF0040; filter: drop-shadow(0 0 20px #FF0040); } -.csm-deepfake:hover .csm-hexagon-icon { color: #FF0040; } -.csm-deepfake .csm-tooltip { border-color: #FF0040; } -.csm-deepfake .csm-tooltip::after { border-left-color: #FF0040; } -.csm-deepfake .csm-tooltip-title { color: #FF0040; } +@keyframes csm-rainbow-stroke { + 0% { stroke: #00FF41; filter: drop-shadow(0 0 20px #00FF41); } + 25% { stroke: #00FFFF; filter: drop-shadow(0 0 20px #00FFFF); } + 50% { stroke: #FF00FF; filter: drop-shadow(0 0 20px #FF00FF); } + 75% { stroke: #FF6600; filter: drop-shadow(0 0 20px #FF6600); } + 100% { stroke: #00FF41; filter: drop-shadow(0 0 20px #00FF41); } +} +@keyframes csm-rainbow-color { + 0% { color: #00FF41; } + 25% { color: #00FFFF; } + 50% { color: #FF00FF; } + 75% { color: #FF6600; } + 100% { color: #00FF41; } +} +@keyframes csm-rainbow-border { + 0% { border-color: #00FF41; } + 25% { border-color: #00FFFF; } + 50% { border-color: #FF00FF; } + 75% { border-color: #FF6600; } + 100% { border-color: #00FF41; } +} + +.csm-deepfake .csm-hexagon-bg { + animation: csm-rainbow-stroke 3s linear infinite; +} +.csm-deepfake .csm-hexagon-icon { + animation: csm-rainbow-color 3s linear infinite; +} +.csm-deepfake:hover .csm-hexagon-bg { animation-duration: 1s; } +.csm-deepfake:hover .csm-hexagon-icon { animation-duration: 1s; } +.csm-deepfake .csm-tooltip { + animation: csm-rainbow-border 3s linear infinite; +} +.csm-deepfake .csm-tooltip::after { border-left-color: #FF00FF; } +.csm-deepfake .csm-tooltip-title { + animation: csm-rainbow-color 3s linear infinite; +} + +.csm-level-5:hover .csm-hexagon-bg { stroke: #a855f7; filter: drop-shadow(0 0 20px #a855f7); } +.csm-level-5:hover .csm-hexagon-icon { color: #a855f7; } +.csm-level-5 .csm-tooltip { border-color: #a855f7; } +.csm-level-5 .csm-tooltip::after { border-left-color: #a855f7; } +.csm-level-5 .csm-tooltip-title { color: #a855f7; } /* Bottom Container */ .csm-bottom-container { @@ -325,7 +363,7 @@ right: 0; display: flex; justify-content: space-between; - padding: 0 80px; + padding: 0 140px; z-index: 20; } diff --git a/src/cases/CybersecMenu.tsx b/src/cases/CybersecMenu.tsx index 7c985cf..f9debbd 100644 --- a/src/cases/CybersecMenu.tsx +++ b/src/cases/CybersecMenu.tsx @@ -35,13 +35,15 @@ const CybersecMenu: React.FC = ({ onSelectLevel, onOpenWiki, const selectLevel = useCallback((level: number | string) => { const levelNames: Record = { - 1: 'Phishing – Fake emails & links', - 2: 'Skimming – ATM/card fraud', - 3: 'Password cracking – Brute force & dictionary', - 4: 'Social engineering – Manipulation', - 'deepfake': 'Voice deepfake – AI-generated speech', + 1: 'Устаревшее ПО — обновление системы', + 2: 'Рабочая среда — базовые угрозы', + 3: 'Фишинг — поддельное письмо Госуслуг', + 4: 'Публичная сеть — защита через VPN', + 5: 'Веб-скимминг — поддельный магазин', + 'deepfake': 'Дипфейк — ИИ-генерация голоса', }; - showNotification(`>> LEVEL ${level} SELECTED`, levelNames[level]); + const label = typeof level === 'number' ? `УРОВЕНЬ ${level}` : level.toUpperCase(); + showNotification(`>> ${label} ВЫБРАН`, levelNames[level]); onSelectLevel?.(level); }, [showNotification, onSelectLevel]); @@ -63,7 +65,8 @@ const CybersecMenu: React.FC = ({ onSelectLevel, onOpenWiki, '2': () => selectLevel(2), '3': () => selectLevel(3), '4': () => selectLevel(4), - '5': () => selectLevel('deepfake'), + '5': () => selectLevel(5), + '6': () => selectLevel('deepfake'), 'w': openWiki, 'W': openWiki, 'q': openQuiz, 'Q': openQuiz, }; @@ -209,11 +212,12 @@ const CybersecMenu: React.FC = ({ onSelectLevel, onOpenWiki, }, []); const menuItems = [ - { level: 1 as number | string, cls: 'csm-level-1', icon: '🔒', title: 'Level 1', desc: 'Phishing – Fake emails & links' }, - { level: 2 as number | string, cls: 'csm-level-2', icon: '⌨️', title: 'Level 2', desc: 'Skimming – ATM/card fraud' }, - { level: 3 as number | string, cls: 'csm-level-3', icon: '🖥️', title: 'Level 3', desc: 'Password cracking – Brute force & dictionary' }, - { level: 4 as number | string, cls: 'csm-level-4', icon: '🛡️', title: 'Level 4', desc: 'Social engineering – Manipulation' }, - { level: 'deepfake', cls: 'csm-deepfake', icon: '🎭', title: 'Deepfake', desc: 'Voice deepfake – AI-generated speech' }, + { level: 1 as number | string, cls: 'csm-level-1', icon: '💻', title: 'Уровень 1', desc: 'Устаревшее ПО — обновление системы' }, + { level: 2 as number | string, cls: 'csm-level-2', icon: '🖥️', title: 'Уровень 2', desc: 'Рабочая среда — базовые угрозы' }, + { level: 3 as number | string, cls: 'csm-level-3', icon: '📧', title: 'Уровень 3', desc: 'Фишинг — поддельное письмо Госуслуг' }, + { level: 4 as number | string, cls: 'csm-level-4', icon: '📶', title: 'Уровень 4', desc: 'Публичная сеть — защита через VPN' }, + { level: 5 as number | string, cls: 'csm-level-5', icon: '💳', title: 'Уровень 5', desc: 'Веб-скимминг — поддельный магазин' }, + { level: 'deepfake', cls: 'csm-deepfake', icon: '🎭', title: 'Дипфейк', desc: 'Дипфейк — ИИ-генерация голоса' }, ]; return ( @@ -344,14 +348,14 @@ const CybersecMenu: React.FC = ({ onSelectLevel, onOpenWiki, 📖 WIKI
-
Security knowledge base
+
База знаний по безопастности
QUIZ
-
Test your skills
+
Проверь свои знания!
diff --git a/src/components/deepfake/ChatterboxTTS.css b/src/components/deepfake/ChatterboxTTS.css index 8a30b98..219714f 100644 --- a/src/components/deepfake/ChatterboxTTS.css +++ b/src/components/deepfake/ChatterboxTTS.css @@ -1,18 +1,39 @@ .chatterbox-container { max-width: 600px; margin: 0 auto; - background: white; - border-radius: 20px; + background: #0d0d22; + border-radius: 12px; padding: 40px; - box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + border: 1px solid rgba(0,255,255,0.2); + box-shadow: 0 0 40px rgba(0,255,255,0.06); + font-family: 'Share Tech Mono', monospace; +} + +.chatterbox-container p { + color: #aaa; + font-size: 13px; + line-height: 1.7; + margin-bottom: 16px; +} + +.chatterbox-container h2 { + color: #00FFFF; + font-family: 'Orbitron', monospace; + font-size: 14px; + font-weight: 700; + margin: 24px 0 12px; + letter-spacing: 1px; } .chatterbox-container h1 { text-align: center; - color: #333; + color: #00FFFF; margin-bottom: 30px; - font-size: 28px; + font-size: 22px; + font-family: 'Orbitron', monospace; + font-weight: 700; + text-shadow: 0 0 20px rgba(0,255,255,0.5); + letter-spacing: 2px; } .form-group { @@ -22,9 +43,10 @@ .form-group label { display: block; margin-bottom: 8px; - color: #555; - font-weight: 500; - font-size: 14px; + color: #888; + font-size: 12px; + letter-spacing: 1px; + text-transform: uppercase; } .form-group input[type="text"], @@ -33,10 +55,13 @@ .form-group textarea { width: 100%; padding: 12px 16px; - border: 2px solid #e0e0e0; - border-radius: 10px; - font-size: 15px; - transition: border-color 0.3s; + background: #080818; + border: 1px solid rgba(0,255,255,0.2); + border-radius: 6px; + font-size: 14px; + color: #ddd; + font-family: 'Share Tech Mono', monospace; + transition: border-color 0.2s; box-sizing: border-box; } @@ -44,7 +69,13 @@ .form-group select:focus, .form-group textarea:focus { outline: none; - border-color: #667eea; + border-color: #00FFFF; + box-shadow: 0 0 8px rgba(0,255,255,0.2); +} + +.form-group select option { + background: #0d0d22; + color: #ddd; } .form-group textarea { @@ -54,109 +85,119 @@ .char-counter { text-align: right; - font-size: 12px; - color: #999; + font-size: 11px; + color: #555; margin-top: 5px; } /* Voice section */ .voice-section { - background: #f8f9ff; - border-radius: 15px; + background: #080818; + border-radius: 8px; padding: 25px; margin-bottom: 25px; - border: 2px solid #e0e0e0; + border: 1px solid rgba(0,255,255,0.15); } .voice-section.recording { - border-color: #e74c3c; - background: #fdf2f2; + border-color: #FF0040; + box-shadow: 0 0 16px rgba(255,0,64,0.15); } .voice-section.has-recording { - border-color: #4caf50; - background: #f1f8f4; + border-color: #00FF41; + box-shadow: 0 0 16px rgba(0,255,65,0.1); } .voice-label { - font-size: 16px; + font-size: 13px; font-weight: 600; - color: #333; + color: #00FFFF; margin-bottom: 15px; display: flex; align-items: center; gap: 10px; + font-family: 'Orbitron', monospace; + letter-spacing: 1px; } .check-badge { display: inline-flex; align-items: center; gap: 5px; - background: #4caf50; - color: white; - padding: 4px 12px; + background: rgba(0,255,65,0.15); + border: 1px solid #00FF41; + color: #00FF41; + padding: 3px 10px; border-radius: 20px; - font-size: 12px; + font-size: 11px; margin-left: 10px; + font-family: 'Share Tech Mono', monospace; } .record-btn { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border: none; + background: rgba(0,255,255,0.1); + border: 2px solid #00FFFF; + color: #00FFFF; border-radius: 50%; width: 70px; height: 70px; font-size: 28px; cursor: pointer; - transition: all 0.3s; + transition: all 0.2s; display: flex; align-items: center; justify-content: center; margin: 0 auto; - box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4); + box-shadow: 0 0 20px rgba(0,255,255,0.2); } .record-btn:hover { - transform: scale(1.1); + background: rgba(0,255,255,0.2); + box-shadow: 0 0 30px rgba(0,255,255,0.4); + transform: scale(1.05); } .record-btn.recording { - background: #e74c3c; - animation: pulse 1.5s infinite; + background: rgba(255,0,64,0.15); + border-color: #FF0040; + color: #FF0040; + box-shadow: 0 0 20px rgba(255,0,64,0.3); + animation: ctb-pulse 1.5s infinite; } -@keyframes pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.1); } +@keyframes ctb-pulse { + 0%, 100% { transform: scale(1); box-shadow: 0 0 20px rgba(255,0,64,0.3); } + 50% { transform: scale(1.08); box-shadow: 0 0 35px rgba(255,0,64,0.5); } } .record-status { text-align: center; margin-top: 15px; color: #666; - font-size: 14px; + font-size: 13px; } .record-timer { text-align: center; font-size: 24px; font-weight: 700; - color: #667eea; + color: #FF0040; margin-top: 10px; - font-family: monospace; + font-family: 'Orbitron', monospace; + text-shadow: 0 0 10px rgba(255,0,64,0.5); } .voice-text { - background: white; - border-radius: 10px; - padding: 20px; + background: rgba(0,255,255,0.04); + border: 1px dashed rgba(0,255,255,0.3); + border-radius: 8px; + padding: 16px 20px; margin-top: 20px; text-align: center; - font-size: 18px; - font-weight: 600; - color: #333; - border: 2px dashed #667eea; + font-size: 14px; + color: #aaa; + line-height: 1.6; } .voice-preview { @@ -165,6 +206,7 @@ .voice-preview audio { width: 100%; + filter: invert(1) hue-rotate(180deg); } .voice-actions { @@ -176,30 +218,44 @@ .voice-actions button { flex: 1; padding: 10px; - border-radius: 8px; - border: none; + border-radius: 6px; cursor: pointer; - font-size: 14px; + font-size: 13px; + font-family: 'Share Tech Mono', monospace; font-weight: 600; + transition: all 0.2s; } .btn-retry { - background: #e0e0e0; - color: #333; + background: transparent; + border: 1px solid rgba(255,255,255,0.15); + color: #888; +} + +.btn-retry:hover { + border-color: #f5a623; + color: #f5a623; } .btn-use { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; + background: rgba(0,255,65,0.1); + border: 1px solid #00FF41; + color: #00FF41; +} + +.btn-use:hover { + background: rgba(0,255,65,0.2); + box-shadow: 0 0 12px rgba(0,255,65,0.3); } /* File upload */ .or-divider { text-align: center; margin: 20px 0; - color: #999; - font-size: 14px; + color: #444; + font-size: 12px; position: relative; + letter-spacing: 2px; } .or-divider::before, @@ -209,35 +265,40 @@ top: 50%; width: 40%; height: 1px; - background: #e0e0e0; + background: rgba(0,255,255,0.1); } .or-divider::before { left: 0; } .or-divider::after { right: 0; } .file-input-wrapper { - border: 2px dashed #ccc; - border-radius: 10px; + border: 1px dashed rgba(0,255,255,0.2); + border-radius: 8px; padding: 20px; text-align: center; cursor: pointer; - transition: all 0.3s; + transition: all 0.2s; + color: #666; + font-size: 13px; } .file-input-wrapper:hover { - border-color: #667eea; - background: #f8f9ff; + border-color: #00FFFF; + background: rgba(0,255,255,0.04); + color: #00FFFF; } .file-input-wrapper.has-file { - border-color: #4caf50; - background: #f1f8f4; + border-color: #00FF41; + background: rgba(0,255,65,0.04); + color: #00FF41; } .file-name { margin-top: 10px; font-weight: 600; - color: #667eea; + color: #00FFFF; + font-size: 13px; } /* Sliders */ @@ -249,13 +310,16 @@ .slider-group input[type="range"] { flex: 1; + accent-color: #00FFFF; } .slider-value { min-width: 50px; text-align: center; font-weight: 600; - color: #667eea; + color: #00FFFF; + font-family: 'Orbitron', monospace; + font-size: 13px; } .two-col { @@ -267,24 +331,26 @@ /* Submit */ .submit-btn { width: 100%; - padding: 16px; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - color: white; - border: none; - border-radius: 10px; - font-size: 16px; - font-weight: 600; + padding: 14px; + background: rgba(0,255,65,0.1); + border: 1px solid #00FF41; + color: #00FF41; + border-radius: 8px; + font-size: 14px; + font-family: 'Orbitron', monospace; + font-weight: 700; cursor: pointer; - transition: transform 0.2s, box-shadow 0.2s; + letter-spacing: 2px; + transition: all 0.2s; } .submit-btn:hover:not(:disabled) { - transform: translateY(-2px); - box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4); + background: rgba(0,255,65,0.2); + box-shadow: 0 0 20px rgba(0,255,65,0.3); } .submit-btn:disabled { - opacity: 0.6; + opacity: 0.4; cursor: not-allowed; } @@ -292,43 +358,51 @@ .loading-block { text-align: center; margin-top: 20px; + color: #666; + font-size: 13px; } .spinner { - width: 40px; - height: 40px; - border: 4px solid #f3f3f3; - border-top: 4px solid #667eea; + width: 36px; + height: 36px; + border: 2px solid rgba(0,255,255,0.15); + border-top: 2px solid #00FFFF; border-radius: 50%; - animation: spin 1s linear infinite; + animation: ctb-spin 0.8s linear infinite; margin: 0 auto 15px; } -@keyframes spin { - 0% { transform: rotate(0deg); } +@keyframes ctb-spin { + 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Error */ .error-block { - color: #e74c3c; - background: #fdf2f2; - padding: 15px; - border-radius: 8px; + color: #FF0040; + background: rgba(255,0,64,0.08); + border: 1px solid rgba(255,0,64,0.3); + padding: 14px; + border-radius: 6px; margin-top: 20px; + font-size: 13px; } /* Result */ .result-block { margin-top: 30px; padding: 20px; - background: #f8f9fa; - border-radius: 10px; + background: rgba(0,255,65,0.04); + border: 1px solid rgba(0,255,65,0.2); + border-radius: 8px; } .result-block h3 { margin-bottom: 15px; - color: #333; + color: #00FF41; + font-family: 'Orbitron', monospace; + font-size: 14px; + letter-spacing: 1px; } .result-block audio { @@ -339,10 +413,17 @@ .download-btn { display: inline-block; margin-top: 15px; - padding: 10px 20px; - background: #4caf50; - color: white; + padding: 9px 20px; + background: rgba(0,255,65,0.1); + border: 1px solid #00FF41; + color: #00FF41; text-decoration: none; - border-radius: 8px; - font-size: 14px; + border-radius: 6px; + font-size: 13px; + font-family: 'Share Tech Mono', monospace; + transition: all 0.2s; +} + +.download-btn:hover { + background: rgba(0,255,65,0.2); } diff --git a/src/components/deepfake/ChatterboxTTS.tsx b/src/components/deepfake/ChatterboxTTS.tsx index 0bfc190..a17baaf 100644 --- a/src/components/deepfake/ChatterboxTTS.tsx +++ b/src/components/deepfake/ChatterboxTTS.tsx @@ -249,7 +249,7 @@ const ChatterboxTTS = () => { {showVoiceText && (
- 📢 Произнесите, например: "Хакатон 2026 походим модуль deepfake, кейс Цент Инвест команда Атейкин" + 📢 Произнесите, например: "Хакатон 2026 походим модуль deepfake, кейс Цент Инвест команда Атейкин"
)} @@ -274,7 +274,7 @@ const ChatterboxTTS = () => { onDragOver={(e) => { e.preventDefault(); setIsDragOver(true); }} onDragLeave={() => setIsDragOver(false)} onDrop={handleDrop} - style={isDragOver ? { borderColor: '#667eea' } : undefined} + style={isDragOver ? { borderColor: '#00FFFF' } : undefined} >
{fileName ? '✅ Файл выбран' : '📁 Кликни или перетащи аудио файл'}
diff --git a/src/components/deepfake/VoiceCards.css b/src/components/deepfake/VoiceCards.css index 79f5747..f05bfb8 100644 --- a/src/components/deepfake/VoiceCards.css +++ b/src/components/deepfake/VoiceCards.css @@ -1,36 +1,44 @@ .voice-cards { display: flex; flex-direction: column; - gap: 24px; + gap: 20px; margin-top: 8px; } /* ── Карточка-сценарий ── */ .voice-card { - background: #1e1e2e; - border-radius: 16px; + background: #080818; + border: 1px solid rgba(0,255,255,0.15); + border-radius: 10px; padding: 16px 18px; display: flex; flex-direction: column; gap: 10px; - box-shadow: 0 4px 20px rgba(0,0,0,.35); + box-shadow: 0 4px 20px rgba(0,0,0,.4); + transition: border-color 0.2s; +} + +.voice-card:hover { + border-color: rgba(0,255,255,0.3); } .voice-card-scenario { font-size: 11px; font-weight: 700; - letter-spacing: .08em; + letter-spacing: .1em; text-transform: uppercase; - color: #a78bfa; + color: #00FFFF; + font-family: 'Orbitron', monospace; } .voice-card-quote { font-size: 13px; - color: #c4c4d4; - line-height: 1.5; - border-left: 3px solid #7c3aed; + color: #aaa; + line-height: 1.6; + border-left: 2px solid #00FFFF; padding-left: 10px; margin: 0; + font-family: 'Share Tech Mono', monospace; } /* ── Аудиосообщение (Telegram-стиль) ── */ @@ -38,7 +46,8 @@ display: flex; align-items: center; gap: 10px; - background: #2a2a3e; + background: #0d0d22; + border: 1px solid rgba(0,255,255,0.1); border-radius: 22px; padding: 10px 14px; } @@ -49,38 +58,42 @@ height: 40px; min-width: 40px; border-radius: 50%; - border: none; - background: #7c3aed; - color: #fff; + border: 1px solid #00FFFF; + background: rgba(0,255,255,0.1); + color: #00FFFF; font-size: 14px; cursor: pointer; display: flex; align-items: center; justify-content: center; - transition: background .15s; + transition: all 0.15s; position: relative; } -.audio-msg-btn:hover { background: #6d28d9; } -.audio-msg-btn.loading { - background: #3f3f5a; - cursor: default; - animation: pulse 1.2s ease-in-out infinite; +.audio-msg-btn:hover { + background: rgba(0,255,255,0.2); + box-shadow: 0 0 12px rgba(0,255,255,0.3); } -@keyframes pulse { +.audio-msg-btn.loading { + border-color: rgba(0,255,255,0.3); + background: rgba(0,255,255,0.05); + cursor: default; + animation: vc-pulse 1.2s ease-in-out infinite; +} +@keyframes vc-pulse { 0%, 100% { opacity: 1; } - 50% { opacity: .5; } + 50% { opacity: .4; } } /* Спиннер внутри кнопки */ .audio-spinner { - width: 18px; - height: 18px; - border: 2px solid rgba(255,255,255,.3); - border-top-color: #fff; + width: 16px; + height: 16px; + border: 2px solid rgba(0,255,255,0.2); + border-top-color: #00FFFF; border-radius: 50%; - animation: spin .7s linear infinite; + animation: vc-spin .7s linear infinite; } -@keyframes spin { to { transform: rotate(360deg); } } +@keyframes vc-spin { to { transform: rotate(360deg); } } /* Волна + прогресс */ .audio-msg-wave { @@ -102,42 +115,45 @@ .waveform-bar { flex: 1; border-radius: 2px; - background: #4b4b6e; + background: rgba(0,255,255,0.15); transition: background .1s; } .waveform-bar.played { - background: #7c3aed; + background: #00FFFF; } .audio-msg-time { font-size: 11px; - color: #6b6b8a; + color: #555; font-variant-numeric: tabular-nums; + font-family: 'Share Tech Mono', monospace; } /* Кнопка перегенерации */ .regen-btn { background: none; - border: 1px solid #3f3f5a; - color: #a0a0c0; + border: 1px solid rgba(0,255,255,0.2); + color: #666; border-radius: 20px; padding: 5px 12px; - font-size: 12px; + font-size: 11px; cursor: pointer; align-self: flex-end; + font-family: 'Share Tech Mono', monospace; transition: border-color .15s, color .15s; } .regen-btn:hover:not(:disabled) { - border-color: #7c3aed; - color: #a78bfa; + border-color: #00FFFF; + color: #00FFFF; } -.regen-btn:disabled { opacity: .4; cursor: default; } +.regen-btn:disabled { opacity: .3; cursor: default; } /* Ошибка */ .voice-card-error { font-size: 12px; - color: #f87171; + color: #FF0040; display: flex; align-items: center; gap: 6px; + font-family: 'Share Tech Mono', monospace; }