File size: 31,691 Bytes
6ea712c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<link rel="icon" href="https://raw.githubusercontent.com/Bella288/F1View/main/images/favicon.ico" type="image/x-icon">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>F1 Car Parts Explorer</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root { --primary-bg: #18181b; --primary-text: #fff; --modal-bg: #1a1a1a; --modal-border: #e10600; --tooltip-bg: rgba(0, 0, 0, 0.8);}
[data-theme="light"] { --primary-bg: #f6f6f6; --primary-text: #18181b; --modal-bg: #fff; --modal-border: #e10600; --tooltip-bg: rgba(60, 60, 60, 0.95);}
html, body { background: var(--primary-bg); color: var(--primary-text);}
.car-container { position: relative; width: 100%; max-width: 800px; margin: 0 auto; aspect-ratio: 16/9; background: #101010;}
.car-container img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; user-select: none;}
.car-part { position: absolute; cursor: pointer; transition: all 0.3s ease; z-index: 10; width: 40px; height: 40px; border-radius: 50%; background: rgba(225,6,0,0.18); border: 2px solid white; box-sizing: border-box; outline: none; transform: translate(-50%, -50%);}
.car-part:focus { outline: 3px solid #e10600; box-shadow: 0 0 0 3px #fff, 0 0 8px #e10600;}
.car-part:active { background: rgba(225,6,0,0.34);}
.car-part:hover { transform: translate(-50%, -50%) scale(1.05); filter: drop-shadow(0 0 8px rgba(255, 215, 0, 0.7));}
.part-tooltip { position: absolute; background-color: var(--tooltip-bg); color: white; padding: 5px 10px; border-radius: 4px; font-size: 12px; pointer-events: none; z-index: 20; opacity: 0; transition: opacity 0.3s; white-space: nowrap; left: 50%; transform: translateX(-50%);}
.car-part:hover .part-tooltip, .car-part:focus .part-tooltip { opacity: 1;}
.modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); z-index: 100; justify-content: center; align-items: center;}
.modal-content { background-color: var(--modal-bg); color: var(--primary-text); border-radius: 10px; width: 95%; max-width: 520px; padding: 20px; position: relative; border: 2px solid var(--modal-border); box-shadow: 0 0 20px rgba(225, 6, 0, 0.5);}
.close-modal { position: absolute; top: 10px; right: 10px; font-size: 24px; cursor: pointer; color: #e10600;}
.tab-button { transition: all 0.3s;}
.tab-button.active { background-color: #e10600; color: white;}
.darkmode-toggle { position: fixed; top: 18px; right: 72px; z-index: 200; background: var(--modal-bg); border: 2px solid var(--modal-border); border-radius: 9999px; padding: 6px 12px; cursor: pointer; display: flex; align-items: center; box-shadow: 0 2px 18px 0 rgba(0,0,0,0.18); transition: background 0.2s, color 0.2s;}
.darkmode-toggle:focus { outline: 2px solid #e10600;}
.about-btn { position: fixed; top: 18px; right: 18px; z-index: 201; background: var(--modal-bg); border: 2px solid var(--modal-border); border-radius: 16px; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; transition: box-shadow 0.2s;}
.about-btn img { width: 22px; height: 22px; pointer-events: none;}
.about-btn:focus { outline: 2px solid #e10600; box-shadow: 0 0 0 3px #fff, 0 0 8px #e10600;}
.about-tooltip { position: absolute; top: 44px; right: 0; background: var(--tooltip-bg); color: white; padding: 6px 12px; border-radius: 6px; font-size: 13px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity 0.2s; z-index: 202;}
.about-btn:hover + .about-tooltip, .about-btn:focus + .about-tooltip { opacity: 1;}
@media (max-width: 640px) {
.car-part { width: 30px !important; height: 30px !important;}
.part-tooltip { font-size: 10px; padding: 3px 6px;}
.darkmode-toggle, .about-btn { top: 10px; right: 12px; padding: 2px 8px;}
.about-btn { top: 10px; right: 10px; width: 30px; height: 30px;}
.about-btn img { width: 16px; height: 16px;}
.about-tooltip { top: 36px; font-size: 11px;}
}
.wheel-container { position: relative; width: 100%; max-width: 960px; margin: 0 auto; aspect-ratio: 16/9; background: #111;}
.wheel-container img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; user-select: none;}
.wheel-hotspot { position: absolute; width: 36px; height: 36px; background: rgba(0,123,255,0.13); border: 2px solid #e10600; border-radius: 50%; cursor: pointer; z-index: 20; transition: background 0.2s, transform 0.2s; box-shadow: 0 0 0 1px #fff4; transform: translate(-50%, -50%);}
.wheel-hotspot:hover { background: rgba(0,123,255,0.35); transform: translate(-50%, -50%) scale(1.1); box-shadow: 0 0 12px #e10600;}
.wheel-tooltip { position: absolute; left: 50%; top: -38px; transform: translateX(-50%); font-size: 14px; padding: 4px 10px; background: var(--tooltip-bg); color: #fff; border-radius: 6px; pointer-events: none; white-space: nowrap; z-index: 1000; opacity: 0; transition: opacity 0.2s;}
.wheel-hotspot:hover .wheel-tooltip, .wheel-hotspot:focus .wheel-tooltip { opacity: 1;}
.wheel-modal-bg { display: none; position: fixed; left:0;top:0;width:100vw;height:100vh; background: rgba(0,0,0,0.7); z-index: 2000; justify-content: center; align-items: center;}
.wheel-modal-bg.show { display: flex; }
.wheel-modal { background: var(--modal-bg); color: var(--primary-text); border-radius: 14px; padding: 30px 28px 20px 28px; min-width: 260px; max-width: 90vw; border: 2px solid #e10600; box-shadow: 0 8px 32px #000b; position: relative;}
.wheel-modal-close { position: absolute; top: 10px; right: 16px; font-size: 27px; color: #e10600; cursor: pointer;}
@media (max-width: 800px) { .wheel-container { width: 100vw !important; max-width: none !important; } }
</style>
</head>
<body class="min-h-screen">
<button class="darkmode-toggle" id="darkmode-toggle" aria-label="Toggle dark mode" tabindex="0">
<span id="darkmode-icon" aria-hidden="true"><i class="fas fa-moon"></i></span>
</button>
<button class="about-btn" id="about-btn" aria-label="About the creator" tabindex="0">
<img src="https://raw.githubusercontent.com/Bella288/F1View/main/images/about_ico.png" alt="About Me">
</button>
<span class="about-tooltip" id="about-tooltip">Learn about the creator</span>
<div id="about-modal" class="modal" style="display: none;">
<div class="modal-content" style="max-width: 390px;">
<span class="close-modal" id="close-about-modal" aria-label="Close creator modal" tabindex="0">×</span>
<h2 class="text-2xl font-bold mb-4 text-red-600">About the Creator</h2>
<div class="text-gray-300 mb-2">
<p>Hi! I'm <b>Bella Lawrence</b>, an HTML and Python programmer from Fort Wayne, Indiana.</p>
<p>I made this for my Dad and Sister who like Formula 1.</p>
<p><b>YouTube:</b> <a href="https://www.youtube.com/@SerialDesignationN-BL" class="text-blue-400 underline" target="_blank" rel="noopener">@SerialDesignationN-BL</a></p>
<p><b>Source:</b> <a href="https://github.com/Bella288/F1View" class="text-blue-400 underline" target="_blank" rel="noopener">github.com/Bella288/F1View</a></p>
<p><b>GitHub:</b> <a href="https://github.com/Bella288" class="text-blue-400 underline" target="_blank" rel="noopener">@Bella288</a></p>
</div>
</div>
</div>
<div class="container mx-auto px-4 py-8">
<header class="text-center mb-8">
<h1 class="text-4xl md:text-5xl font-bold mb-2 text-red-600">F1 CAR EXPLORER</h1>
<p class="text-gray-300 max-w-2xl mx-auto">Interactive guide to Formula 1 car components. Click on any part to learn more.</p>
</header>
<div class="flex justify-center mb-6">
<div class="inline-flex rounded-md shadow-sm" role="group">
<button id="exterior-btn" class="tab-button px-4 py-2 text-sm font-medium rounded-l-lg bg-gray-800 hover:bg-gray-700 active" aria-label="Show Exterior View" tabindex="0">
<i class="fas fa-car mr-2" aria-hidden="true"></i>Exterior
</button>
<button id="interior-btn" class="tab-button px-4 py-2 text-sm font-medium bg-gray-800 hover:bg-gray-700" aria-label="Show Interior View" tabindex="0">
<i class="fas fa-tachometer-alt mr-2" aria-hidden="true"></i>Interior
</button>
<button id="wheel-btn" class="tab-button px-4 py-2 text-sm font-medium rounded-r-lg bg-gray-800 hover:bg-gray-700" aria-label="Show Steering Wheel" tabindex="0">
<i class="fas fa-circle-notch mr-2" aria-hidden="true"></i>Steering Wheel
</button>
</div>
</div>
<div id="exterior-view" class="car-container">
<img src="images/F1_EXTERIOR.jpg" alt="F1 Car">
<div class="car-part" style="left:90.63%; top:58.15%;" data-part="front-wing" aria-label="Front Wing" tabindex="0"><div class="part-tooltip" style="top:-38px;">Front Wing</div></div>
<div class="car-part" style="left:85.94%; top:53.89%;" data-part="nose" aria-label="Nose" tabindex="0"><div class="part-tooltip" style="top:-38px;">Nose</div></div>
<div class="car-part" style="left:48.65%; top:52.22%;" data-part="sidepods" aria-label="Sidepods" tabindex="0"><div class="part-tooltip" style="top:-38px;">Sidepods</div></div>
<div class="car-part" style="left:60.63%; top:40.56%;" data-part="halo" aria-label="Halo" tabindex="0"><div class="part-tooltip" style="top:-38px;">Halo</div></div>
<div class="car-part" style="left:13.75%; top:46.85%;" data-part="rear-wing" aria-label="Rear Wing" tabindex="0"><div class="part-tooltip" style="top:-38px;">Rear Wing</div></div>
<div class="car-part" style="left:26.04%; top:61.11%;" data-part="diffuser" aria-label="Diffuser" tabindex="0"><div class="part-tooltip" style="top:46px;">Diffuser</div></div>
<div class="car-part" style="left:78.96%; top:56.30%;" data-part="wheels" aria-label="Wheels" tabindex="0"><div class="part-tooltip" style="top:-38px;">Wheels</div></div>
<div class="car-part" style="left:16.15%; top:38.33%;" data-part="drs" aria-label="DRS" tabindex="0"><div class="part-tooltip" style="top:-38px;">DRS</div></div>
<div class="car-part" style="left:19.79%; top:55.74%;" data-part="wheels" aria-label="Wheels" tabindex="0"><div class="part-tooltip" style="top:-38px;">Wheels</div></div>
</div>
<div id="interior-view" class="car-container hidden">
<img src="images/F1_INTERIOR.jpg" alt="F1 Car Interior">
<div class="car-part" style="left:54.38%; top:69.39%;" data-part="steering-wheel" aria-label="Steering Wheel" tabindex="0"><div class="part-tooltip" style="top:-38px;">Steering Wheel</div></div>
<div class="car-part" style="left:53.44%; top:78.54%;" data-part="pedals" aria-label="Pedals" tabindex="0"><div class="part-tooltip" style="top:46px;">Pedals</div></div>
<div class="car-part" style="left:53.50%; top:90.41%;" data-part="seat" aria-label="Seat" tabindex="0"><div class="part-tooltip" style="top:-38px;">Seat</div></div>
<div class="car-part" style="left:54.38%; top:49.70%;" data-part="halo-interior" aria-label="Halo (Interior)" tabindex="0"><div class="part-tooltip" style="top:-38px;">Halo</div></div>
<div class="car-part" style="left:22.94%; top:48.54%;" data-part="wheels" aria-label="Wheels" tabindex="0"><div class="part-tooltip" style="top:-38px;">Wheels</div></div>
<div class="car-part" style="left:76.75%; top:44.67%;" data-part="wheels" aria-label="Wheels" tabindex="0"><div class="part-tooltip" style="top:-38px;">Wheels</div></div>
</div>
<div id="wheel-view" class="wheel-container hidden">
<img src="https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/interior/steer.webp" alt="F1 Steering Wheel" draggable="false">
</div>
<div class="wheel-modal-bg" id="wheel-modal-bg">
<div class="wheel-modal" id="wheel-modal">
<span class="wheel-modal-close" id="wheel-modal-close" tabindex="0">×</span>
<h2 id="wheel-modal-title" class="text-xl font-bold mb-2 text-red-600"></h2>
<p id="wheel-modal-desc" class="mb-2"></p>
</div>
</div>
<div id="part-modal" class="modal" aria-modal="true" role="dialog">
<div class="modal-content">
<span class="close-modal" aria-label="Close part modal" tabindex="0">×</span>
<h2 id="part-name" class="text-2xl font-bold mb-4 text-red-600"></h2>
<div id="part-description" class="text-gray-300 mb-2"></div>
<div id="part-image" class="mb-3"></div>
<div id="part-facts" class="mt-4 p-4 bg-gray-800 rounded-lg hidden">
<h3 class="font-bold text-red-500 mb-2">Fun Fact</h3>
<p id="fact-text"></p>
</div>
<div id="part-learnmore" class="mt-3"></div>
</div>
</div>
<script>
const exteriorBtn = document.getElementById('exterior-btn');
const interiorBtn = document.getElementById('interior-btn');
const wheelBtn = document.getElementById('wheel-btn');
const exteriorView = document.getElementById('exterior-view');
const interiorView = document.getElementById('interior-view');
const wheelView = document.getElementById('wheel-view');
exteriorBtn.addEventListener('click', () => {
exteriorBtn.classList.add('active');
interiorBtn.classList.remove('active');
wheelBtn.classList.remove('active');
exteriorView.classList.remove('hidden');
interiorView.classList.add('hidden');
wheelView.classList.add('hidden');
});
interiorBtn.addEventListener('click', () => {
interiorBtn.classList.add('active');
exteriorBtn.classList.remove('active');
wheelBtn.classList.remove('active');
exteriorView.classList.add('hidden');
interiorView.classList.remove('hidden');
wheelView.classList.add('hidden');
});
wheelBtn.addEventListener('click', () => {
wheelBtn.classList.add('active');
exteriorBtn.classList.remove('active');
interiorBtn.classList.remove('active');
exteriorView.classList.add('hidden');
interiorView.classList.add('hidden');
wheelView.classList.remove('hidden');
});
const carPartData = {
'front-wing': { name: 'Front Wing', description: 'The front wing is the first point of contact for airflow and is fundamental to a car’s aerodynamic performance. It\'s made from multiple elements and endplates to direct airflow around the car.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/frontwing.webp' },
'nose': { name: 'Nose Cone', description: 'The nose cone is the forward-most structure, designed to pass stringent crash tests while being as aerodynamic and lightweight as possible.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/nose.jpg' },
'sidepods': { name: 'Sidepods', description: 'Sidepods house radiators, electronics, and sometimes cooling for the hybrid system. Their outer surfaces are sculpted to channel air efficiently to the rear of the car.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/sidepods.jpg' },
'halo': { name: 'Halo Safety Device', description: 'The halo is a titanium structure mounted above the cockpit to protect the driver’s head from debris or other cars.', fact: 'The halo can withstand the weight of a London bus.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/halo.jpg' },
'rear-wing': { name: 'Rear Wing', description: 'The rear wing provides crucial downforce, helping maintain grip at high speeds and during cornering.', fact: 'At full speed, the rear wing produces enough downforce to flip a car upside down.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/rearwing.jpg' },
'diffuser': { name: 'Diffuser', description: 'The diffuser is the upward-swept rear section of the floor, essential for generating ground effect downforce.', fact: 'A well-designed diffuser can contribute as much as 40% of a car’s total downforce.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/diffuser.jpg' },
'wheels': { name: 'Wheels', description: 'F1 wheels are made from high-strength magnesium alloy, combining lightness and durability. They are fitted with Pirelli tires, which are slick for dry and treaded for wet conditions.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/tyre.jpg' },
'drs': { name: 'DRS (Drag Reduction System)', description: 'The Drag Reduction System (DRS) allows drivers to open a flap in the rear wing when within one second of a car ahead, reducing drag and increasing top speed.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/exterior/drs.gif' },
'steering-wheel': { name: 'Steering Wheel', description: 'An F1 steering wheel is an advanced control center, featuring more than 20 buttons, rotary switches, and paddles. Drivers use it to change settings, communicate, and control the car.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/interior/steer.webp' },
'pedals': { name: 'Pedals', description: 'F1 cars have just two pedals: brake (left) and throttle (right). The brake pedal operates carbon-carbon brakes capable of generating over 5G of deceleration.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/interior/pedals.jpg' },
'seat': { name: "Driver's Seat", description: "The seat is custom-molded to each driver using foam or resin, providing maximum support and safety during high G-force events.", fact: "Drivers spend hours sitting in their seat during fittings for a perfect mold.", image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/interior/seat.png' },
'halo-interior': { name: 'Halo (Interior View)', description: 'From inside the cockpit, the halo appears as a central pillar and two side arms, framing the driver\'s field of vision.', image: 'https://raw.githubusercontent.com/Bella288/F1View/main/images/parts/interior/halo.png' }
};
function showCarPartModal(partId) {
const modal = document.getElementById('part-modal');
const partName = document.getElementById('part-name');
const partDescription = document.getElementById('part-description');
const partFacts = document.getElementById('part-facts');
const factText = document.getElementById('fact-text');
const partImage = document.getElementById('part-image');
const partLearnMore = document.getElementById('part-learnmore');
const data = carPartData[partId];
partName.textContent = data ? data.name : partId;
partDescription.textContent = data ? data.description : '';
if (data && data.fact) {
partFacts.classList.remove('hidden');
factText.textContent = data.fact;
} else {
partFacts.classList.add('hidden');
}
if (data && data.image) {
partImage.innerHTML = `<img src="${data.image}" alt="${data.name}" class="rounded-lg shadow mb-2" style="max-width: 100%; max-height:140px; display:block;margin:0 auto;">`;
} else {
partImage.innerHTML = '';
}
if (data && data.link) {
partLearnMore.innerHTML = `<a href="${data.link}" class="text-blue-400 underline" target="_blank" rel="noopener">Learn more</a>`;
} else {
partLearnMore.innerHTML = '';
}
modal.style.display = 'flex';
document.body.style.overflow = 'hidden';
modal.querySelector('.close-modal').focus();
}
function hideCarPartModal() {
const modal = document.getElementById('part-modal');
modal.style.display = 'none';
document.body.style.overflow = '';
}
document.querySelectorAll('.car-part').forEach(part => {
part.addEventListener('click', function() {
showCarPartModal(this.getAttribute('data-part'));
});
part.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
showCarPartModal(this.getAttribute('data-part'));
}
});
});
document.querySelectorAll('.close-modal').forEach(el => {
el.addEventListener('click', hideCarPartModal);
el.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') hideCarPartModal();
});
});
window.addEventListener('keydown', e => {
const modal = document.getElementById('part-modal');
if (e.key === "Escape" && modal.style.display === 'flex') hideCarPartModal();
});
document.getElementById('part-modal').addEventListener('click', e => {
if (e.target === document.getElementById('part-modal')) hideCarPartModal();
});
const wheelHotspotData = [
{ label: "N", x: 343, y: 144, title: "N (Neutral) Button", desc: "Shifts the gearbox into neutral. Essential for pit stops and emergencies." },
{ label: "+10", x: 447, y: 154, title: "+10 Button", desc: "Increases selected parameter (like brake balance, engine mode) by 10 units." },
{ label: "BW", x: 536, y: 212, title: "Brake Magic (BW)", desc: "Reconfigures brake balance for maximum front bias to heat brakes or for safety car restarts." },
{ label: "Entry", x: 273, y: 230, title: "'Entry' Rotary", desc: "Multi-function rotary usually for corner entry settings (diff, brake migration, etc)." },
{ label: "EB", x: 508, y: 360, title: "Engine Braking (EB) Rotary", desc: "Adjusts the engine braking level, affecting how much the engine slows the car off-throttle." },
{ label: "Scroll", x: 444, y: 535, title: "Left Scroll Wheel", desc: "Menu navigation or fine-tuning settings." },
{ label: "MARK", x: 570, y: 480, title: "MARK Button", desc: "Marks a lap/time/event for later engineering analysis." },
{ label: "OK", x: 554, y: 600, title: "OK Button", desc: "Confirms menu choices or acknowledges messages on the dash." },
{ label: "BB-", x: 529, y: 720, title: "BB- (Brake Bias Decrement)", desc: "Reduces brake bias (moves braking rearward) to help with rear locking or instability." },
{ label: "Leds", x: 619, y: 232, title: "Shift Light Strip", desc: "Colored LEDs indicate optimal shift points and/or warnings (blue/yellow/red)." },
{ label: "Screen", x: 947, y: 352, title: "Main Display", desc: "Displays lap times, deltas, fuel, tire wear, engine and ERS modes, DRS, speed, gear, and warnings for driver and engineer." },
{ label: "STRAT", x: 728, y: 698, title: "Strat Mode Rotary", desc: "Selects engine/PU strategy modes (performance mapping, fuel, reliability)." },
{ label: "Settings", x: 952, y: 697, title: "Multi-Function Rotary", desc: "Adjusts various advanced car systems: DEF, BITE, EXIT, INIT, RADIO, TRQ, CRUZ, VOL, REVS, DASH, DISP, BRIG, etc." },
{ label: "HPP", x: 1183, y: 703, title: "HPP Mode Rotary", desc: "Likely adjusts power unit parameters (Hybrid Power Parameters), e.g., ERS deployment, harvesting, shift, etc." },
{ label: "PL", x: 1582, y: 126, title: "PL (Pit Lane) Button", desc: "Activates pit lane speed limiter." },
{ label: "+1", x: 1486, y: 146, title: "+1 Button", desc: "Increases selected parameter by 1 unit." },
{ label: "PC", x: 1383, y: 212, title: "PC (Pit Confirm) Button", desc: "Confirms pit instruction, or used for pit related settings." },
{ label: "MID", x: 1640, y: 230, title: "MID Rotary", desc: "Likely for mid-corner balance or mid-race settings." },
{ label: "BBAL", x: 1400, y: 357, title: "BBAL Rotary", desc: "Selects brake balance preset profiles (BB+, BB-, etc)." },
{ label: "ACS", x: 1347, y: 488, title: "ACS Button", desc: "Quick access to engine/hybrid adjustments." },
{ label: "Scroll", x: 1457, y: 532, title: "Right Scroll Wheel", desc: "Menu navigation or fine-tuning settings." },
{ label: "TALK", x: 1362, y: 608, title: "Radio (Talk) Button", desc: "Activates the driver's radio for communication with the pit wall." },
{ label: "BB+", x: 1377, y: 723, title: "BB+ (Brake Bias Increment)", desc: "Increases brake bias (moves braking forward) to help with front locking or instability." },
{ label: "L Paddle", x: 433, y: 387, title: "Left Paddle", desc: "Gear shift, clutch, or DRS. Used for launches and gear changes." },
{ label: "R Paddle", x: 1488, y: 387, title: "Right Paddle", desc: "Gear shift, clutch, or DRS. Used for launches and gear changes." },
{ label: "LEDs", x: 1296, y: 225, title: "Shift Light Strip", desc: "Colored LEDs indicate optimal shift points and/or warnings." },
{ label: "LED Strip", x: 958, y: 119, title: "Main LED Strip", desc: "Main shift lights and warning indicators." }
];
function createWheelHotspots() {
const wheelView = document.getElementById('wheel-view');
wheelHotspotData.forEach(h => {
const spot = document.createElement('div');
spot.className = 'wheel-hotspot';
spot.style.left = ((h.x / 1920) * 100) + '%';
spot.style.top = ((h.y / 1080) * 100) + '%';
spot.tabIndex = 0;
spot.setAttribute('aria-label', h.title);
const tip = document.createElement('div');
tip.className = 'wheel-tooltip';
tip.textContent = h.title;
spot.appendChild(tip);
spot.addEventListener('click', () => showWheelModal(h.title, h.desc));
spot.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') showWheelModal(h.title, h.desc);
});
wheelView.appendChild(spot);
});
}
function showWheelModal(title, desc) {
document.getElementById('wheel-modal-title').textContent = title;
document.getElementById('wheel-modal-desc').textContent = desc;
document.getElementById('wheel-modal-bg').classList.add('show');
}
function closeWheelModal() {
document.getElementById('wheel-modal-bg').classList.remove('show');
}
document.getElementById('wheel-modal-close').onclick = closeWheelModal;
document.getElementById('wheel-modal-bg').onclick = function(e) {
if(e.target === this) closeWheelModal();
};
window.addEventListener('keydown', e => {
if(e.key === "Escape" && document.getElementById('wheel-modal-bg').classList.contains('show')) closeWheelModal();
});
const aboutBtn = document.getElementById('about-btn');
const aboutModal = document.getElementById('about-modal');
const closeAboutModal = document.getElementById('close-about-modal');
aboutBtn.addEventListener('click', () => {
aboutModal.style.display = 'flex';
document.body.style.overflow = 'hidden';
closeAboutModal.focus();
});
closeAboutModal.addEventListener('click', () => {
aboutModal.style.display = 'none';
document.body.style.overflow = '';
});
closeAboutModal.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') {
aboutModal.style.display = 'none';
document.body.style.overflow = '';
}
});
window.addEventListener('keydown', e => {
if (e.key === "Escape" && aboutModal.style.display === 'flex') {
aboutModal.style.display = 'none';
document.body.style.overflow = '';
}
});
aboutModal.addEventListener('click', e => {
if (e.target === aboutModal) {
aboutModal.style.display = 'none';
document.body.style.overflow = '';
}
});
const darkmodeToggle = document.getElementById('darkmode-toggle');
const darkmodeIcon = document.getElementById('darkmode-icon');
function setTheme(theme) {
if (theme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
darkmodeIcon.innerHTML = '<i class="fas fa-moon"></i>';
} else {
document.documentElement.setAttribute('data-theme', 'light');
darkmodeIcon.innerHTML = '<i class="fas fa-sun"></i>';
}
}
function getSavedTheme() {
return localStorage.getItem('theme') || 'dark';
}
function toggleTheme() {
const current = getSavedTheme();
const newTheme = current === 'dark' ? 'light' : 'dark';
setTheme(newTheme);
localStorage.setItem('theme', newTheme);
}
darkmodeToggle.addEventListener('click', toggleTheme);
setTheme(getSavedTheme());
createWheelHotspots();
</script>
</div>
</body>
</html> |