Will be awesome one day, I guarantee you
1const VERSION_BASE = '29.04.2026.';
2const STORAGE_KEY = 'nepastoucherTime';
3const GAMEOVER_STORAGE_KEY = 'gameoverTime';
4const WARNING_DURATION_MS = 10 * 60 * 1000;
5
6const versionEl = document.getElementById('compteur');
7const contentEl = document.getElementById('content');
8const preventionEl = document.getElementById('prevention');
9const choiceButtons = document.querySelectorAll('.nepastoucher');
10const counterButton = document.getElementById('compteurplusun');
11const buyAutoClickButton = document.getElementById('achatautoclick');
12const gameOverButton = document.getElementById('gameover');
13
14const state = {
15 counter: 1,
16 autoClickCount: 0,
17 autoClickAccumulator: 0,
18 versionFlashColor: '',
19 versionFlashExpiry: 0,
20 autoClickInterval: 1000,
21 isGameOver: false,
22 fallingElements: [],
23 baseGravity: 0.0009,
24 bounceDamping: 0.6
25};
26
27const formatVersion = () => `Version: ${VERSION_BASE}${state.counter}`;
28
29const updateVersionText = () => {
30 versionEl.textContent = formatVersion();
31};
32
33const flashVersion = (color, duration = 500) => {
34 state.versionFlashColor = color;
35 state.versionFlashExpiry = performance.now() + duration;
36 versionEl.style.color = color;
37};
38
39const getAutoClickCost = () => Math.max(1, Math.round(5 * state.autoClickCount));
40
41const applyWarningEffect = () => {
42 contentEl.classList.add('rotated');
43 preventionEl.classList.remove('hidden');
44 choiceButtons.forEach(button => button.classList.add('hidden'));
45};
46
47const saveWarningTime = () => {
48 localStorage.setItem(STORAGE_KEY, Date.now().toString());
49};
50
51const loadWarningState = () => {
52 const storedTime = localStorage.getItem(STORAGE_KEY);
53 if (!storedTime) {
54 return;
55 }
56
57 const elapsed = Date.now() - Number(storedTime);
58 if (elapsed < WARNING_DURATION_MS) {
59 applyWarningEffect();
60 } else {
61 localStorage.removeItem(STORAGE_KEY);
62 }
63};
64
65const saveGameOverTime = () => {
66 localStorage.setItem(GAMEOVER_STORAGE_KEY, Date.now().toString());
67};
68
69const loadGameOverState = () => {
70 const storedTime = localStorage.getItem(GAMEOVER_STORAGE_KEY);
71 if (!storedTime) {
72 return;
73 }
74
75 const elapsed = Date.now() - Number(storedTime);
76 if (elapsed < WARNING_DURATION_MS) {
77 state.isGameOver = true;
78 const allButtons = document.querySelectorAll('button');
79 allButtons.forEach(button => {
80 button.disabled = true;
81 });
82 prepareFallingElements();
83 // Move all elements to bottom position immediately
84 state.fallingElements.forEach(entry => {
85 entry.settled = true;
86 entry.velocity = 0;
87 const bottomLimit = window.innerHeight - entry.height;
88 entry.top = bottomLimit;
89 entry.node.style.top = `${entry.top}px`;
90 });
91 } else {
92 localStorage.removeItem(GAMEOVER_STORAGE_KEY);
93 }
94};
95
96const prepareFallingElements = () => {
97 const elements = Array.from(document.querySelectorAll('p, button, h1, h2'));
98
99 // First pass: capture all positions before any DOM changes
100 const elementData = elements.map(node => {
101 const rect = node.getBoundingClientRect();
102 return {
103 node,
104 left: rect.left,
105 top: rect.top,
106 width: rect.width,
107 height: rect.height
108 };
109 });
110
111 // Second pass: apply positioning and create fall entries
112 elementData.forEach(data => {
113 const { node, left, top, width, height } = data;
114
115 node.style.position = 'fixed';
116 node.style.left = `${left}px`;
117 node.style.top = `${top}px`;
118 node.style.width = `${width}px`;
119 node.style.height = `${height}px`;
120 node.style.margin = '0';
121 node.style.padding = node.style.padding || '';
122 node.style.boxSizing = 'border-box';
123 node.style.transition = 'none';
124
125 state.fallingElements.push({
126 node,
127 top,
128 width,
129 height,
130 velocity: (Math.random() - 0.5) * 0.3,
131 gravity: state.baseGravity * (0.5 + Math.random()),
132 bounceDamping: state.bounceDamping * (0.5 + Math.random() * 0.5),
133 settled: false
134 });
135 });
136};
137
138const startGameOverFall = () => {
139 if (state.isGameOver) {
140 return;
141 }
142
143 state.isGameOver = true;
144 saveGameOverTime();
145
146 // Disable all buttons
147 const allButtons = document.querySelectorAll('button');
148 allButtons.forEach(button => {
149 button.disabled = true;
150 });
151
152 prepareFallingElements();
153};
154
155const tick = (delta) => {
156 if (state.autoClickCount > 0) {
157 state.autoClickAccumulator += delta;
158 const clicks = Math.floor(state.autoClickAccumulator / state.autoClickInterval) * state.autoClickCount;
159 if (clicks > 0) {
160 state.autoClickAccumulator %= state.autoClickInterval;
161 state.counter += clicks;
162 updateVersionText();
163 }
164 }
165
166 if (state.isGameOver) {
167 state.fallingElements.forEach(entry => {
168 // Apply gravity
169 entry.velocity += entry.gravity * delta;
170 entry.top += entry.velocity * delta;
171
172 const bottomLimit = window.innerHeight - entry.height;
173
174 // Bounce collision
175 if (entry.top >= bottomLimit) {
176 entry.top = bottomLimit;
177 entry.velocity *= -entry.bounceDamping;
178
179 // Stop bouncing when velocity is very small
180 if (Math.abs(entry.velocity) < 0.1) {
181 entry.velocity = 0;
182 entry.settled = true;
183 }
184 }
185
186 entry.node.style.top = `${entry.top}px`;
187 });
188 }
189
190 if (state.versionFlashExpiry && performance.now() >= state.versionFlashExpiry) {
191 state.versionFlashColor = '';
192 state.versionFlashExpiry = 0;
193 versionEl.style.color = '';
194 }
195};
196
197const gameLoop = (timestamp) => {
198 if (!gameLoop.lastTime) {
199 gameLoop.lastTime = timestamp;
200 }
201
202 const delta = timestamp - gameLoop.lastTime;
203 gameLoop.lastTime = timestamp;
204
205 tick(delta);
206 requestAnimationFrame(gameLoop);
207};
208
209const init = () => {
210 updateVersionText();
211 loadWarningState();
212 loadGameOverState();
213
214 choiceButtons.forEach(button => {
215 button.addEventListener('click', () => {
216 saveWarningTime();
217 applyWarningEffect();
218 });
219 });
220
221 counterButton.addEventListener('click', () => {
222 state.counter += 1;
223 updateVersionText();
224 flashVersion('green', 300);
225 });
226
227 buyAutoClickButton.addEventListener('click', () => {
228 const cost = getAutoClickCost();
229 if (state.counter >= cost) {
230 state.counter -= cost;
231 state.autoClickCount += 1;
232 updateVersionText();
233 flashVersion('yellow', 1000);
234 } else {
235 flashVersion('red', 1000);
236 }
237 });
238
239 gameOverButton.addEventListener('click', () => {
240 startGameOverFall();
241 });
242
243 requestAnimationFrame(gameLoop);
244};
245
246document.addEventListener('DOMContentLoaded', init);