1 2<!DOCTYPE html> 3<html lang="uk" class="scroll-smooth"> 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>ÐÑдгоÑовка опеÑаÑоÑÑв ЧÐÐ | KPIK</title> 8
8<script src="https://cdn.tailwindcss.com"></script>
8 9 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet"> 10 <style> 11 body { font-family: 'Inter', sans-serif; overflow-x: hidden; } 12 .glass { background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(10px); } 13 .industrial-gradient { background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); } 14 15 @keyframes fadeInUp { 16 from { opacity: 0; transform: translateY(30px); } 17 to { opacity: 1; transform: translateY(0); } 18 } 19 20 @keyframes fadeIn { 21 from { opacity: 0; } 22 to { opacity: 1; } 23 } 24 25 @keyframes scaleIn { 26 from { opacity: 0; transform: scale(0.95); } 27 to { opacity: 1; transform: scale(1); } 28 } 29 30 @keyframes kenBurns { 31 0% { transform: scale(1) translate(0, 0); } 32 50% { transform: scale(1.1) translate(-1%, -1%); } 33 100% { transform: scale(1) translate(0, 0); } 34 } 35 36 @keyframes gridMove { 37 0% { background-position: 0 0; } 38 100% { background-position: 100px 100px; } 39 } 40 41 @keyframes noise { 42 0%, 100% { transform: translate(0,0); } 43 10% { transform: translate(-5%,-5%); } 44 20% { transform: translate(-10%,5%); } 45 30% { transform: translate(5%,-10%); } 46 40% { transform: translate(-5%,15%); } 47 50% { transform: translate(-10%,5%); } 48 60% { transform: translate(15%,0); } 49 70% { transform: translate(0,10%); } 50 80% { transform: translate(-15%,0); } 51 90% { transform: translate(10%,5%); } 52 } 53 54 .animate-fade-in-up { animation: fadeInUp 0.8s ease-out forwards; } 55 .animate-fade-in { animation: fadeIn 1s ease-out forwards; } 56 .animate-scale-in { animation: scaleIn 0.5s ease-out forwards; } 57 .animate-ken-burns { animation: kenBurns 30s ease-in-out infinite; } 58 .will-change-transform { will-change: transform; } 59 60 .tech-grid { 61 background-image: 62 linear-gradient(rgba(59, 130, 246, 0.2) 1.5px, transparent 1.5px), 63 linear-gradient(90deg, rgba(59, 130, 246, 0.2) 1.5px, transparent 1.5px), 64 linear-gradient(rgba(59, 130, 246, 0.05) 1px, transparent 1px), 65 linear-gradient(90deg, rgba(59, 130, 246, 0.05) 1px, transparent 1px); 66 background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px; 67 animation: gridMove 30s linear infinite; 68 } 69 70 .grain-overlay { 71 position: absolute; 72 width: 200%; 73 height: 200%; 74 top: -50%; 75 left: -50%; 76 background-image: url("https://grainy-gradients.vercel.app/noise.svg"); 77 opacity: 0.12; 78 pointer-events: none; 79 z-index: 25; 80 animation: noise 0.5s steps(10) infinite; 81 } 82 83 .reveal { 84 opacity: 0; 85 transform: translateY(30px); 86 transition: all 0.8s ease-out; 87 } 88 89 .reveal.active { 90 opacity: 1; 91 transform: translateY(0); 92 } 93 94 .stagger-1 { animation-delay: 0.1s; } 95 .stagger-2 { animation-delay: 0.2s; } 96 .stagger-3 { animation-delay: 0.3s; } 97 98 .z-25 { z-index: 25; } 99 100 .page-transition-enter { 101 animation: fadeIn 0.4s ease-in-out; 102 } 103 </style> 104
105<script type="importmap"> 106{ 107 "imports": { 108 "react": "https://esm.sh/react@^19.2.4", 109 "react-dom/": "https://esm.sh/react-dom@^19.2.4/", 110 "react/": "https://esm.sh/react@^19.2.4/", 111 "@google/genai": "https://esm.sh/@google/genai@^1.40.0", 112 "vite": "https://esm.sh/vite@^7.3.1", 113 "@vitejs/plugin-react": "https://esm.sh/@vitejs/plugin-react@^5.1.4" 114 } 115} 116</script>
116 117
117<script type="module" crossorigin src="/assets/index-Dc5DZ9yy.js"></script>
117 118</head> 119<body class="bg-gray-50 text-slate-900"> 120 <div id="root"></div> 121
121<script> 122 const observerOptions = { threshold: 0.1 }; 123 const observer = new IntersectionObserver((entries) => { 124 entries.forEach(entry => { 125 if (entry.isIntersecting) { 126 entry.target.classList.add('active'); 127 } 128 }); 129 }, observerOptions); 130 131 window.addEventListener('scroll_reveal_init', () => { 132 document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); 133 }); 134 135 document.addEventListener('DOMContentLoaded', () => { 136 window.dispatchEvent(new Event('scroll_reveal_init')); 137 }); 138 </script>
138 139</body> 140</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.