448 lines
20 KiB
HTML
448 lines
20 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>PPE Safety Challenge - Choose Right. Work Safe.</title>
|
||
<link rel="stylesheet" href="css/styles.css">
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@600;700&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
||
</head>
|
||
<body>
|
||
<!-- App Container -->
|
||
<div id="app-root" class="app-container">
|
||
|
||
<!-- Top Navigation / Header Bar -->
|
||
<header class="top-bar">
|
||
<div class="brand-badge">
|
||
<div class="safety-helmet-icon">
|
||
<svg viewBox="0 0 36 36" class="helmet-svg">
|
||
<path d="M 6 22 C 6 12 30 12 30 22 L 34 24 C 34 26 2 26 2 24 Z" fill="#facc15" stroke="#ca8a04" stroke-width="1.5"/>
|
||
<path d="M 14 11 L 22 11 L 21 23 L 15 23 Z" fill="#eab308"/>
|
||
<rect x="3" y="23" width="30" height="3" rx="1.5" fill="#ca8a04"/>
|
||
</svg>
|
||
</div>
|
||
<div class="brand-text">
|
||
<span class="game-title">PPE SAFETY CHALLENGE</span>
|
||
<span class="game-tagline">CHOOSE RIGHT. WORK SAFE.</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hud-center">
|
||
<div class="scenario-stepper" id="scenario-stepper">
|
||
<div class="step-pill active" id="step-pill-1">
|
||
<span class="step-num">1</span>
|
||
<span class="step-label">Grinding Ops</span>
|
||
</div>
|
||
<div class="step-dots">·······</div>
|
||
<div class="step-pill" id="step-pill-2">
|
||
<span class="step-num">2</span>
|
||
<span class="step-label">Chemical Handling</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hud-right">
|
||
<div class="score-display">
|
||
<span class="score-label">SAFETY SCORE</span>
|
||
<span class="score-val" id="hud-score">0</span>
|
||
<span class="score-star-icon">★</span>
|
||
<span class="score-stars-sub" id="hud-stars">☆</span>
|
||
</div>
|
||
|
||
<!-- Audio & Settings Controls -->
|
||
<button id="btn-sound-toggle" class="btn-icon-hud" title="Sound Effects (S)" aria-label="Sound Toggle">
|
||
<span>🔊</span>
|
||
</button>
|
||
<button id="btn-music-toggle" class="btn-icon-hud" title="Music Toggle (M)" aria-label="Music Toggle">
|
||
<span>🎵</span>
|
||
</button>
|
||
<button id="btn-audio-settings" class="btn-icon-hud" title="Audio Settings (O)" aria-label="Audio Settings">
|
||
<span>⚙️</span>
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Main Dynamic Screen Container -->
|
||
<main id="main-viewport" class="main-viewport">
|
||
|
||
<!-- SCREEN 1: START / INTRO SCREEN -->
|
||
<section id="screen-start" class="screen-view active">
|
||
<div class="intro-card">
|
||
<div class="hero-graphic">
|
||
<div class="safety-shield-animated">
|
||
<svg viewBox="0 0 100 100" class="shield-svg">
|
||
<polygon points="50,5 92,20 92,55 50,95 8,55 8,20" class="shield-outline" />
|
||
<path d="M50 25 L50 75 M25 50 L75 50" class="shield-plus" />
|
||
</svg>
|
||
<div class="pulse-ring"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<h1 class="hero-title">PPE SAFETY CHALLENGE</h1>
|
||
<p class="hero-subtitle">“Choose Right. Work Safe.”</p>
|
||
|
||
<div class="mission-briefing">
|
||
<h3>Interactive Workplace Safety Mission</h3>
|
||
<p>Select the correct Personal Protective Equipment (PPE) for critical industrial tasks. Learn how proper gear prevents severe workplace injuries before starting dangerous operations.</p>
|
||
|
||
<div class="learning-flow-banner">
|
||
<span class="flow-item">🔍 SEE SITUATION</span>
|
||
<span class="flow-arrow">➔</span>
|
||
<span class="flow-item">⚠️ IDENTIFY HAZARD</span>
|
||
<span class="flow-arrow">➔</span>
|
||
<span class="flow-item">🦺 SELECT PPE</span>
|
||
<span class="flow-arrow">➔</span>
|
||
<span class="flow-item">⚙️ START TASK</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="start-controls">
|
||
<button id="btn-start-game" class="btn btn-primary btn-large glow-effect">
|
||
<span class="btn-icon-large">▶</span>
|
||
<span class="btn-text">START CHALLENGE</span>
|
||
</button>
|
||
<div class="controls-hint">
|
||
<span>⌨️ Mouse Click or Number Keys (1-9) to equip • Spacebar to Start Task</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- SCREEN 2: ACTIVE GAMEPLAY VIEW -->
|
||
<section id="screen-game" class="screen-view">
|
||
<div class="gameplay-grid">
|
||
|
||
<!-- Left Column: Hazard Assessment & Worker Protection Status -->
|
||
<aside class="sidebar-hazard-panel card-panel">
|
||
<div class="panel-header">
|
||
<div class="scenario-badge" id="scene-badge">SCENARIO 1 OF 2</div>
|
||
<h2 class="scenario-title" id="scene-title">Chemical Handling & Dispensing</h2>
|
||
<p class="situation-desc" id="scene-desc">
|
||
An employee is transferring an industrial corrosive solvent between approved containers at a ventilated dispensing station.
|
||
</p>
|
||
</div>
|
||
|
||
<!-- Identify Hazards Box -->
|
||
<div class="hazard-identification-card">
|
||
<div class="card-subtitle-small">IDENTIFY THE HAZARDS</div>
|
||
<ul class="hazard-list" id="hazard-list">
|
||
<!-- Dynamically populated -->
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- Worker Protection Status with Wireframe Silhouette -->
|
||
<div class="worker-protection-card">
|
||
<div class="card-subtitle-small">WORKER PROTECTION STATUS</div>
|
||
<div class="protection-status-content">
|
||
<!-- Blue Wireframe Silhouette -->
|
||
<div class="body-silhouette-box">
|
||
<svg viewBox="0 0 100 200" class="wireframe-body-svg">
|
||
<!-- Head -->
|
||
<circle cx="50" cy="24" r="14" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||
<!-- Neck -->
|
||
<line x1="50" y1="38" x2="50" y2="46" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||
<!-- Shoulders & Torso -->
|
||
<path d="M 24 55 L 76 55 L 68 115 L 32 115 Z" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||
<!-- Left Arm -->
|
||
<path d="M 24 55 L 12 105 L 10 140" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||
<!-- Right Arm -->
|
||
<path d="M 76 55 L 88 105 L 90 140" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||
<!-- Left Leg -->
|
||
<path d="M 38 115 L 34 165 L 32 195" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||
<!-- Right Leg -->
|
||
<path d="M 62 115 L 66 165 L 68 195" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||
</svg>
|
||
</div>
|
||
|
||
<!-- Status Rows -->
|
||
<div class="protection-rows" id="coverage-grid">
|
||
<div class="status-row-item" data-slot="head">
|
||
<span class="row-icon">🧢</span>
|
||
<span class="row-label">Head</span>
|
||
<span class="row-badge status-q">?</span>
|
||
</div>
|
||
<div class="status-row-item" data-slot="eyes">
|
||
<span class="row-icon">👓</span>
|
||
<span class="row-label">Eyes / Face</span>
|
||
<span class="row-badge status-q">?</span>
|
||
</div>
|
||
<div class="status-row-item" data-slot="ears">
|
||
<span class="row-icon">🎧</span>
|
||
<span class="row-label">Hearing</span>
|
||
<span class="row-badge status-q">?</span>
|
||
</div>
|
||
<div class="status-row-item" data-slot="hands">
|
||
<span class="row-icon">🧤</span>
|
||
<span class="row-label">Hands</span>
|
||
<span class="row-badge status-q">?</span>
|
||
</div>
|
||
<div class="status-row-item" data-slot="body">
|
||
<span class="row-icon">🦺</span>
|
||
<span class="row-label">Body</span>
|
||
<span class="row-badge status-q">?</span>
|
||
</div>
|
||
<div class="status-row-item" data-slot="feet">
|
||
<span class="row-icon">🥾</span>
|
||
<span class="row-label">Feet</span>
|
||
<span class="row-badge status-q">?</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tip Box -->
|
||
<div class="tip-card">
|
||
<div class="tip-title">💡 TIP</div>
|
||
<p class="tip-text" id="locker-guide-text">
|
||
Observe the scene, identify the hazards and select the correct PPE before starting the task.
|
||
</p>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- Middle Column: Interactive Scene & Worker Avatar -->
|
||
<div class="center-stage-panel card-panel">
|
||
<div class="scene-environment-container" id="scene-stage">
|
||
<!-- Scene canvas for particles/sparks/chemicals -->
|
||
<canvas id="stage-fx-canvas" class="stage-fx-canvas"></canvas>
|
||
|
||
<!-- Dynamic Background Scenery Layer -->
|
||
<div class="scene-backdrop" id="scene-backdrop">
|
||
<!-- Dynamically populated based on scenario -->
|
||
</div>
|
||
|
||
<!-- Worker Avatar Interactive SVG Layer -->
|
||
<div class="avatar-wrapper" id="avatar-container">
|
||
<!-- Injected by avatar.js -->
|
||
</div>
|
||
|
||
<!-- Freeze Frame / Critical Warning Alert Overlay -->
|
||
<div class="consequence-freeze-overlay" id="consequence-overlay">
|
||
<div class="freeze-banner">
|
||
<div class="freeze-header">
|
||
<span class="hazard-flasher" id="hazard-flasher-badge">⚠️ STOP! CRITICAL HAZARDS DETECTED</span>
|
||
</div>
|
||
<h3 class="consequence-title" id="consequence-title">Critical Protection Gaps Detected</h3>
|
||
<p class="consequence-desc" id="consequence-desc">
|
||
Multiple required protective gear items are missing or improper for this task. Unprotected body zones are exposed to severe workplace trauma.
|
||
</p>
|
||
|
||
<div class="missing-items-box">
|
||
<div class="missing-box-header">
|
||
<span class="box-label">⚠️ ALL REQUIRED CORRECTIONS (<span id="missing-count-num">0</span> ISSUES):</span>
|
||
</div>
|
||
<div class="missing-hazard-cards" id="consequence-hazard-list">
|
||
<!-- Dynamically rendered list of all missing & incorrect items -->
|
||
</div>
|
||
</div>
|
||
|
||
<button id="btn-fix-ppe" class="btn btn-warning glow-effect">
|
||
<span>🔧 FIX ALL WORKER PPE & RETRY</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Success Overlay Banner -->
|
||
<div class="success-overlay" id="success-overlay">
|
||
<div class="success-banner">
|
||
<div class="success-badge">
|
||
<span class="badge-icon">✅</span>
|
||
<span class="badge-title" id="success-title">SAFE TO START</span>
|
||
</div>
|
||
<p class="success-desc" id="success-desc">
|
||
Correct PPE selected. Your eyes, face, hands, hearing and feet are fully protected against all task hazards.
|
||
</p>
|
||
<div class="points-awarded-pill">
|
||
<span class="star-icon">⭐</span>
|
||
<span class="points-text" id="awarded-points-text">+100 Safety Points</span>
|
||
</div>
|
||
<button id="btn-next-scenario" class="btn btn-success glow-effect">
|
||
<span id="btn-next-scenario-text">NEXT SCENARIO ➔</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Right Column: PPE Selection Locker (3x3 Grid) & Action Buttons -->
|
||
<aside class="sidebar-locker-panel card-panel">
|
||
<div class="panel-header-locker">
|
||
<div class="locker-title-row">
|
||
<span class="locker-icon">🦺</span>
|
||
<h3 class="locker-title">PPE SAFETY LOCKER</h3>
|
||
</div>
|
||
<p class="locker-subtitle">Select and equip the correct PPE for this task.</p>
|
||
<p class="locker-instruction">Click an item to equip on the worker.</p>
|
||
</div>
|
||
|
||
<!-- 3x3 Equipment Grid -->
|
||
<div class="ppe-locker-grid" id="ppe-locker-grid">
|
||
<!-- Dynamically populated based on scenario (9 items in 3 columns) -->
|
||
</div>
|
||
|
||
<!-- Locker Action Buttons -->
|
||
<div class="locker-actions-dock">
|
||
<button id="btn-check-ppe" class="btn btn-check-ppe">
|
||
<span class="btn-check-icon">✓</span>
|
||
<span>CHECK MY PPE</span>
|
||
</button>
|
||
|
||
<button id="btn-test-safety" class="btn btn-start-task glow-ready">
|
||
<span class="btn-play-icon">▶</span>
|
||
<span id="btn-test-safety-text">START TASK</span>
|
||
</button>
|
||
</div>
|
||
</aside>
|
||
|
||
</div>
|
||
</section>
|
||
|
||
<!-- SCREEN 3: COMPLETION / FINAL SCORE SCREEN -->
|
||
<section id="screen-summary" class="screen-view">
|
||
<div class="summary-card">
|
||
<div class="summary-header">
|
||
<div class="victory-trophy">🏆</div>
|
||
<h1 class="summary-title">PPE SAFETY CHALLENGE COMPLETE</h1>
|
||
<p class="summary-subtitle">“Choose Right. Work Safe.”</p>
|
||
</div>
|
||
|
||
<div class="metrics-dashboard">
|
||
<div class="metric-box">
|
||
<span class="metric-label">FINAL SAFETY SCORE</span>
|
||
<span class="metric-val" id="summary-score">200 / 200</span>
|
||
<span class="metric-sub" id="summary-percentage">100% Safety Compliance</span>
|
||
</div>
|
||
<div class="metric-box">
|
||
<span class="metric-label">SCENARIOS COMPLETED</span>
|
||
<span class="metric-val">2 / 2</span>
|
||
<span class="metric-sub">Zero Workplace Accidents</span>
|
||
</div>
|
||
<div class="metric-box">
|
||
<span class="metric-label">SAFETY STARS</span>
|
||
<span class="metric-val star-gold" id="summary-stars">⭐⭐</span>
|
||
<span class="metric-sub" id="summary-rank">Master Safety Practitioner</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Key Takeaway Mantra -->
|
||
<div class="takeaway-banner">
|
||
<div class="takeaway-heading">CORE SAFETY WORKFLOW</div>
|
||
<div class="mantra-chain">
|
||
<div class="mantra-step">🛑 <strong>STOP</strong></div>
|
||
<div class="mantra-arrow">➔</div>
|
||
<div class="mantra-step">👁️ <strong>LOOK</strong></div>
|
||
<div class="mantra-arrow">➔</div>
|
||
<div class="mantra-step">⚠️ <strong>IDENTIFY HAZARDS</strong></div>
|
||
<div class="mantra-arrow">➔</div>
|
||
<div class="mantra-step">🦺 <strong>SELECT PPE</strong></div>
|
||
<div class="mantra-arrow">➔</div>
|
||
<div class="mantra-step">🛡️ <strong>WORK SAFELY</strong></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Scenarios Review Summary Accordion -->
|
||
<div class="scenarios-review-box">
|
||
<h4>Safety Assessment Summary</h4>
|
||
<div class="review-row">
|
||
<div class="rev-icon">⚡</div>
|
||
<div class="rev-info">
|
||
<strong>Scenario 1: Angle Grinding Operation</strong>
|
||
<p>Protected against flying hot sparks, high decibel noise (95+ dB), and sharp metal burrs using Full Face Shield + Glasses, Leather Grinding Gloves, Hearing Protection & Safety Boots.</p>
|
||
</div>
|
||
<div class="rev-status">✅ PASSED</div>
|
||
</div>
|
||
<div class="review-row">
|
||
<div class="rev-icon">🧪</div>
|
||
<div class="rev-info">
|
||
<strong>Scenario 2: Industrial Chemical Transfer</strong>
|
||
<p>Prevented chemical burn & splash injury using Chemical Splash Goggles, Heavy Nitrile Gauntlet Gloves, Chemical Resistant Apron & Rubber Safety Boots.</p>
|
||
</div>
|
||
<div class="rev-status">✅ PASSED</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="summary-actions">
|
||
<button id="btn-replay" class="btn btn-primary btn-large">
|
||
<span>🔄 REPLAY SAFETY CHALLENGE</span>
|
||
</button>
|
||
<button id="btn-print-certificate" class="btn btn-secondary btn-large">
|
||
<span>📜 PRINT SAFETY CERTIFICATE</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<!-- Audio Settings Modal Dialog -->
|
||
<div class="modal-backdrop" id="modal-audio">
|
||
<div class="modal-card">
|
||
<div class="modal-header">
|
||
<h3>🔊 Audio & Sound Control</h3>
|
||
<button id="btn-close-audio-modal" class="btn-close" aria-label="Close modal">✕</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="audio-control-row">
|
||
<label for="toggle-master-mute">Master Audio</label>
|
||
<input type="checkbox" id="toggle-master-mute" checked>
|
||
</div>
|
||
<div class="audio-control-row">
|
||
<label for="slider-music-vol">Background Music Volume (<span id="music-vol-num">25%</span>)</label>
|
||
<input type="range" id="slider-music-vol" min="0" max="100" value="25">
|
||
</div>
|
||
<div class="audio-control-row">
|
||
<label for="slider-sfx-vol">Sound Effects (SFX) Volume (<span id="sfx-vol-num">55%</span>)</label>
|
||
<input type="range" id="slider-sfx-vol" min="0" max="100" value="55">
|
||
</div>
|
||
<div class="audio-control-row">
|
||
<label for="toggle-ambient-hum">Industrial Ambience Hum</label>
|
||
<input type="checkbox" id="toggle-ambient-hum" checked>
|
||
</div>
|
||
<div class="audio-info-note">
|
||
ℹ️ The game features a real-time Web Audio synthesizer. Audio starts when you click <strong>Start Challenge</strong>. All safety information is also fully visual and accessible when muted.
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button id="btn-save-audio" class="btn btn-primary">Done</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Printable Certificate Template (Hidden until printed) -->
|
||
<div id="printable-certificate" class="printable-certificate">
|
||
<div class="cert-border">
|
||
<div class="cert-header">
|
||
<div class="cert-logo">✚ PPE SAFETY CHALLENGE</div>
|
||
<h1>CERTIFICATE OF SAFETY EXCELLENCE</h1>
|
||
<p class="cert-sub">This certifies that</p>
|
||
<h2 class="cert-name">QUALIFIED INDUSTRIAL EMPLOYEE</h2>
|
||
<p class="cert-desc">has successfully demonstrated 100% competency in Hazard Identification & Personal Protective Equipment (PPE) Selection across all high-risk industrial scenarios.</p>
|
||
</div>
|
||
<div class="cert-footer">
|
||
<div class="cert-signature">
|
||
<div class="sig-line"></div>
|
||
<span>Safety & Environmental Health Officer</span>
|
||
</div>
|
||
<div class="cert-seal">
|
||
⭐ VERIFIED SAFE ⭐
|
||
</div>
|
||
<div class="cert-date">
|
||
<div class="sig-line" id="cert-date-val"></div>
|
||
<span>Completion Date</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Scripts -->
|
||
<script src="js/audio.js"></script>
|
||
<script src="js/scenarios.js"></script>
|
||
<script src="js/particles.js"></script>
|
||
<script src="js/avatar.js"></script>
|
||
<script src="js/game.js"></script>
|
||
</body>
|
||
</html>
|