Skip to content

Instantly share code, notes, and snippets.

@0xD8C4A475
Created March 23, 2026 08:28
Show Gist options
  • Select an option

  • Save 0xD8C4A475/9edbbe5b56cefba09ef10fe5600aef66 to your computer and use it in GitHub Desktop.

Select an option

Save 0xD8C4A475/9edbbe5b56cefba09ef10fe5600aef66 to your computer and use it in GitHub Desktop.
KRESZ Gyakorló - Magyar közlekedési táblák kvíz
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KRESZ Gyakorló</title>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
--bg:#f1f5f9;--card:#ffffff;--primary:#4f46e5;--primary-light:#818cf8;
--correct:#16a34a;--correct-bg:#dcfce7;--wrong:#dc2626;--wrong-bg:#fee2e2;
--text:#1e293b;--text-light:#64748b;--border:#e2e8f0;
--red:#C1121C;--blue:#003DA5;--warn-yellow:#FCBF16;--sign-white:#FFFFFF;
--cat-tilto:#ef4444;--cat-figy:#f59e0b;--cat-utas:#3b82f6;--cat-taj:#06b6d4;
--radius:12px;--shadow:0 1px 3px rgba(0,0,0,.08),0 4px 12px rgba(0,0,0,.04);
}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
background:var(--bg);color:var(--text);min-height:100vh;line-height:1.5}
.container{max-width:640px;margin:0 auto;padding:16px}
h1{font-size:1.6rem;text-align:center;margin:12px 0 4px}
.subtitle{text-align:center;color:var(--text-light);font-size:.95rem;margin-bottom:20px}
/* Start Screen */
#startScreen .logo{text-align:center;margin:20px 0 8px}
#startScreen .logo svg{width:80px;height:80px}
.section-title{font-size:.85rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text-light);margin:20px 0 8px}
.cat-pills{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}
.cat-pill{padding:8px 16px;border-radius:20px;border:2px solid var(--border);background:var(--card);
cursor:pointer;font-size:.9rem;font-weight:500;transition:all .2s;user-select:none}
.cat-pill:hover{border-color:var(--primary-light);background:#eef2ff}
.cat-pill.active{color:#fff;border-color:transparent}
.cat-pill[data-cat="all"].active{background:var(--primary)}
.cat-pill[data-cat="tilto"].active{background:var(--cat-tilto)}
.cat-pill[data-cat="figyelmez"].active{background:var(--cat-figy)}
.cat-pill[data-cat="utasito"].active{background:var(--cat-utas)}
.cat-pill[data-cat="taj"].active{background:var(--cat-taj)}
.count-btns{display:flex;gap:8px;margin-bottom:24px}
.count-btn{flex:1;padding:10px;border-radius:var(--radius);border:2px solid var(--border);background:var(--card);
cursor:pointer;font-size:1rem;font-weight:600;transition:all .2s;text-align:center}
.count-btn:hover{border-color:var(--primary-light)}
.count-btn.active{background:var(--primary);color:#fff;border-color:var(--primary)}
.start-btn{width:100%;padding:14px;border:none;border-radius:var(--radius);
background:linear-gradient(135deg,var(--primary),var(--primary-light));
color:#fff;font-size:1.1rem;font-weight:600;cursor:pointer;transition:transform .15s,box-shadow .15s}
.start-btn:hover{transform:translateY(-1px);box-shadow:0 4px 16px rgba(79,70,229,.35)}
.start-btn:active{transform:translateY(0)}
/* Quiz Screen */
#quizScreen{display:none}
.progress-wrap{background:var(--border);border-radius:8px;height:8px;margin-bottom:16px;overflow:hidden}
.progress-bar{height:100%;border-radius:8px;background:linear-gradient(90deg,var(--primary),var(--primary-light));transition:width .4s ease}
.quiz-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;font-size:.9rem;color:var(--text-light)}
.quiz-header .score{font-weight:600;color:var(--correct)}
.sign-card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);padding:24px;text-align:center;margin-bottom:16px;
transition:opacity .3s,transform .3s}
.sign-card.fade-out{opacity:0;transform:translateY(-10px)}
.sign-card.fade-in{opacity:0;transform:translateY(10px)}
.sign-card svg{width:140px;height:140px;margin:0 auto 12px}
.sign-category{display:inline-block;padding:3px 10px;border-radius:10px;font-size:.75rem;font-weight:600;color:#fff;margin-bottom:8px}
.sign-category.tilto{background:var(--cat-tilto)}
.sign-category.figyelmez{background:var(--cat-figy);color:var(--text)}
.sign-category.utasito{background:var(--cat-utas)}
.sign-category.taj{background:var(--cat-taj)}
.answers{display:flex;flex-direction:column;gap:10px;margin-bottom:16px}
.answer-btn{padding:14px 18px;border:2px solid var(--border);border-radius:var(--radius);background:var(--card);
cursor:pointer;font-size:.95rem;text-align:left;transition:all .2s;min-height:48px;display:flex;align-items:center;gap:10px}
.answer-btn:hover:not(.disabled){border-color:var(--primary-light);background:#f8fafc}
.answer-btn .letter{width:28px;height:28px;border-radius:50%;background:var(--bg);display:flex;align-items:center;justify-content:center;
font-weight:700;font-size:.85rem;flex-shrink:0;transition:all .2s}
.answer-btn.correct{border-color:var(--correct);background:var(--correct-bg)}
.answer-btn.correct .letter{background:var(--correct);color:#fff}
.answer-btn.wrong{border-color:var(--wrong);background:var(--wrong-bg)}
.answer-btn.wrong .letter{background:var(--wrong);color:#fff}
.answer-btn.disabled{pointer-events:none}
.answer-btn.reveal-correct{border-color:var(--correct);background:var(--correct-bg)}
.answer-btn.reveal-correct .letter{background:var(--correct);color:#fff}
.next-btn{width:100%;padding:12px;border:none;border-radius:var(--radius);background:var(--primary);
color:#fff;font-size:1rem;font-weight:600;cursor:pointer;transition:transform .1s;display:none}
.next-btn:hover{background:var(--primary-light)}
.next-btn.visible{display:block}
/* Result Screen */
#resultScreen{display:none}
.result-card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);padding:32px 24px;text-align:center;margin-bottom:20px}
.donut-wrap{position:relative;width:160px;height:160px;margin:0 auto 16px}
.donut{width:160px;height:160px;border-radius:50%}
.donut-center{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
width:100px;height:100px;border-radius:50%;background:var(--card);display:flex;flex-direction:column;align-items:center;justify-content:center}
.donut-pct{font-size:2rem;font-weight:800;line-height:1}
.donut-label{font-size:.8rem;color:var(--text-light)}
.result-msg{font-size:1.2rem;font-weight:600;margin:12px 0 4px}
.result-sub{color:var(--text-light);font-size:.9rem;margin-bottom:16px}
.result-stats{display:flex;justify-content:center;gap:24px;margin-bottom:20px}
.stat{text-align:center}
.stat-val{font-size:1.4rem;font-weight:700}
.stat-label{font-size:.75rem;color:var(--text-light)}
.stat-correct .stat-val{color:var(--correct)}
.stat-wrong .stat-val{color:var(--wrong)}
.wrong-review{margin-top:16px;text-align:left}
.wrong-review h3{font-size:1rem;margin-bottom:12px}
.wrong-item{display:flex;gap:12px;align-items:center;padding:12px;background:var(--wrong-bg);border-radius:var(--radius);margin-bottom:8px}
.wrong-item svg{width:56px;height:56px;flex-shrink:0}
.wrong-detail{flex:1}
.wrong-detail .your-ans{color:var(--wrong);font-size:.85rem;text-decoration:line-through}
.wrong-detail .correct-ans{color:var(--correct);font-size:.85rem;font-weight:600}
.restart-btn{width:100%;padding:14px;border:none;border-radius:var(--radius);
background:linear-gradient(135deg,var(--primary),var(--primary-light));
color:#fff;font-size:1.1rem;font-weight:600;cursor:pointer;margin-top:16px;transition:transform .15s}
.restart-btn:hover{transform:translateY(-1px)}
@media(max-width:480px){
.container{padding:12px}
h1{font-size:1.3rem}
.sign-card svg{width:120px;height:120px}
.cat-pills{gap:6px}
.cat-pill{padding:6px 12px;font-size:.82rem}
}
</style>
</head>
<body>
<div class="container">
<!-- ============ START SCREEN ============ -->
<div id="startScreen">
<div class="logo">
<svg viewBox="0 0 80 80" fill="none">
<rect x="4" y="4" width="72" height="72" rx="16" fill="#4f46e5"/>
<path d="M40 18 L58 56 H22Z" fill="none" stroke="#fff" stroke-width="3.5" stroke-linejoin="round"/>
<circle cx="40" cy="48" r="3" fill="#fff"/>
<rect x="38" y="30" width="4" height="12" rx="2" fill="#fff"/>
</svg>
</div>
<h1>KRESZ Gyakorló</h1>
<p class="subtitle">Ismerd meg a közlekedési táblákat!</p>
<div class="section-title">Kategória</div>
<div class="cat-pills">
<div class="cat-pill active" data-cat="all" onclick="selectCat(this)">Összes</div>
<div class="cat-pill" data-cat="tilto" onclick="selectCat(this)">Tiltó táblák</div>
<div class="cat-pill" data-cat="figyelmez" onclick="selectCat(this)">Figyelmeztető</div>
<div class="cat-pill" data-cat="utasito" onclick="selectCat(this)">Utasító táblák</div>
<div class="cat-pill" data-cat="taj" onclick="selectCat(this)">Tájékoztató</div>
</div>
<div class="section-title">Kérdések száma</div>
<div class="count-btns">
<div class="count-btn active" data-count="10" onclick="selectCount(this)">10</div>
<div class="count-btn" data-count="20" onclick="selectCount(this)">20</div>
<div class="count-btn" data-count="0" onclick="selectCount(this)">Összes</div>
</div>
<button class="start-btn" onclick="startQuiz()">Indítás</button>
</div>
<!-- ============ QUIZ SCREEN ============ -->
<div id="quizScreen">
<div class="progress-wrap"><div class="progress-bar" id="progressBar"></div></div>
<div class="quiz-header">
<span id="questionNum">1 / 10</span>
<span class="score" id="scoreDisplay">0 pont</span>
</div>
<div class="sign-card" id="signCard">
<div id="signSvg"></div>
<span class="sign-category" id="signCat"></span>
</div>
<div class="answers" id="answersDiv"></div>
<button class="next-btn" id="nextBtn" onclick="nextQuestion()">Következő</button>
</div>
<!-- ============ RESULT SCREEN ============ -->
<div id="resultScreen">
<div class="result-card">
<div class="donut-wrap">
<div class="donut" id="donutChart"></div>
<div class="donut-center">
<span class="donut-pct" id="pctText">0%</span>
<span class="donut-label">pontosság</span>
</div>
</div>
<div class="result-msg" id="resultMsg"></div>
<div class="result-sub" id="resultSub"></div>
<div class="result-stats">
<div class="stat stat-correct"><div class="stat-val" id="statCorrect">0</div><div class="stat-label">Helyes</div></div>
<div class="stat"><div class="stat-val" id="statTotal">0</div><div class="stat-label">Kérdés</div></div>
<div class="stat stat-wrong"><div class="stat-val" id="statWrong">0</div><div class="stat-label">Hibás</div></div>
</div>
</div>
<div class="wrong-review" id="wrongReview"></div>
<button class="restart-btn" onclick="restartQuiz()">Újrakezdés</button>
</div>
</div>
<script>
// ===== SVG SIGN DRAWING SYSTEM =====
// Base shape builders
function svgWrap(inner, vb='0 0 120 120'){return `<svg viewBox="${vb}" xmlns="http://www.w3.org/2000/svg">${inner}</svg>`}
function prohibCircle(inner){
return svgWrap(`<circle cx="60" cy="60" r="52" fill="#C1121C"/><circle cx="60" cy="60" r="42" fill="#fff"/>${inner}`);
}
function blueCircle(inner){
return svgWrap(`<circle cx="60" cy="60" r="52" fill="#003DA5"/>${inner}`);
}
function warnTriangle(inner){
return svgWrap(`<path d="M60 10 L110 100 H10Z" fill="#C1121C" stroke="#C1121C" stroke-width="2" stroke-linejoin="round"/>
<path d="M60 20 L104 96 H16Z" fill="#FCBF16" stroke="#FCBF16" stroke-width="1" stroke-linejoin="round"/>${inner}`);
}
function blueSquare(inner){
return svgWrap(`<rect x="8" y="8" width="104" height="104" rx="8" fill="#003DA5"/>${inner}`);
}
function blueRect(inner){
return svgWrap(`<rect x="4" y="16" width="112" height="88" rx="8" fill="#003DA5"/>${inner}`);
}
// Prohibitory signs with red border on blue background
function prohibBlueCircle(inner){
return svgWrap(`<circle cx="60" cy="60" r="52" fill="#C1121C"/><circle cx="60" cy="60" r="46" fill="#003DA5"/>${inner}`);
}
// ===== SIGN DEFINITIONS =====
const signs = [
// ===== TILTÓ TÁBLÁK (9) =====
{
id:'tilto_behajtani',cat:'tilto',catName:'Tiltó táblák',
name:'Behajtani tilos',
svg: svgWrap(`<circle cx="60" cy="60" r="52" fill="#C1121C"/><rect x="24" y="50" width="72" height="20" rx="4" fill="#fff"/>`)
},
{
id:'tilto_mindket',cat:'tilto',catName:'Tiltó táblák',
name:'Mindkét irányból behajtani tilos',
svg: prohibCircle(``)
},
{
id:'tilto_kerekpar',cat:'tilto',catName:'Tiltó táblák',
name:'Kerékpárral behajtani tilos',
svg: prohibCircle(`<g transform="translate(60,62) scale(0.75)"><circle cx="0" cy="12" r="10" fill="none" stroke="#1e293b" stroke-width="4"/><circle cx="0" cy="-14" r="10" fill="none" stroke="#1e293b" stroke-width="4"/><line x1="0" y1="12" x2="0" y2="-14" stroke="#1e293b" stroke-width="3.5"/><line x1="0" y1="-14" x2="-8" y2="-24" stroke="#1e293b" stroke-width="3"/><line x1="0" y1="-14" x2="8" y2="-24" stroke="#1e293b" stroke-width="3"/><line x1="0" y1="-4" x2="10" y2="-10" stroke="#1e293b" stroke-width="3"/></g>`)
},
{
id:'tilto_elozni',cat:'tilto',catName:'Tiltó táblák',
name:'Előzni tilos',
svg: prohibCircle(`<g><rect x="26" y="44" width="16" height="28" rx="6" fill="#1e293b"/><rect x="44" y="44" width="16" height="28" rx="6" fill="#C1121C"/></g>`)
},
{
id:'tilto_30',cat:'tilto',catName:'Tiltó táblák',
name:'Sebességkorlátozás 30 km/h',
svg: prohibCircle(`<text x="60" y="72" text-anchor="middle" font-size="36" font-weight="800" fill="#1e293b" font-family="Arial,sans-serif">30</text>`)
},
{
id:'tilto_50',cat:'tilto',catName:'Tiltó táblák',
name:'Sebességkorlátozás 50 km/h',
svg: prohibCircle(`<text x="60" y="72" text-anchor="middle" font-size="36" font-weight="800" fill="#1e293b" font-family="Arial,sans-serif">50</text>`)
},
{
id:'tilto_70',cat:'tilto',catName:'Tiltó táblák',
name:'Sebességkorlátozás 70 km/h',
svg: prohibCircle(`<text x="60" y="72" text-anchor="middle" font-size="36" font-weight="800" fill="#1e293b" font-family="Arial,sans-serif">70</text>`)
},
{
id:'tilto_megallni',cat:'tilto',catName:'Tiltó táblák',
name:'Megállni tilos',
svg: prohibBlueCircle(`<line x1="30" y1="30" x2="90" y2="90" stroke="#C1121C" stroke-width="7"/><line x1="90" y1="30" x2="30" y2="90" stroke="#C1121C" stroke-width="7"/>`)
},
{
id:'tilto_varakozni',cat:'tilto',catName:'Tiltó táblák',
name:'Várakozni tilos',
svg: prohibBlueCircle(`<line x1="30" y1="30" x2="90" y2="90" stroke="#C1121C" stroke-width="7"/>`)
},
// ===== FIGYELMEZTETŐ TÁBLÁK (9) =====
{
id:'figy_veszely',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Egyéb veszély',
svg: warnTriangle(`<text x="60" y="82" text-anchor="middle" font-size="48" font-weight="900" fill="#1e293b" font-family="Arial,sans-serif">!</text>`)
},
{
id:'figy_jobbra',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Jobbra ívelő kanyar',
svg: warnTriangle(`<path d="M50 80 Q50 55 70 45" fill="none" stroke="#1e293b" stroke-width="6" stroke-linecap="round"/><polygon points="72,38 76,50 64,48" fill="#1e293b"/>`)
},
{
id:'figy_balra',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Balra ívelő kanyar',
svg: warnTriangle(`<path d="M70 80 Q70 55 50 45" fill="none" stroke="#1e293b" stroke-width="6" stroke-linecap="round"/><polygon points="48,38 44,50 56,48" fill="#1e293b"/>`)
},
{
id:'figy_kereszt',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Útkereszteződés',
svg: warnTriangle(`<rect x="55" y="40" width="10" height="46" rx="2" fill="#1e293b"/><rect x="40" y="55" width="40" height="10" rx="2" fill="#1e293b"/>`)
},
{
id:'figy_gyalogos',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Gyalogos-átkelőhely közeledik',
svg: warnTriangle(`<g transform="translate(55,48) scale(0.7)">
<circle cx="0" cy="-12" r="6" fill="#1e293b"/>
<line x1="0" y1="-6" x2="0" y2="18" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="-12" y1="4" x2="12" y2="4" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="0" y1="18" x2="-10" y2="36" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="0" y1="18" x2="10" y2="36" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
</g><g transform="translate(40,76)"><rect x="0" y="0" width="4" height="14" fill="#1e293b"/><rect x="7" y="0" width="4" height="14" fill="#1e293b"/><rect x="14" y="0" width="4" height="14" fill="#1e293b"/></g>`)
},
{
id:'figy_utepites',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Útépítés',
svg: warnTriangle(`<g transform="translate(55,50) scale(0.7)">
<circle cx="0" cy="-12" r="6" fill="#1e293b"/>
<line x1="0" y1="-6" x2="0" y2="18" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="0" y1="4" x2="16" y2="-8" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="0" y1="4" x2="-14" y2="0" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="0" y1="18" x2="-10" y2="36" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="0" y1="18" x2="10" y2="36" stroke="#1e293b" stroke-width="4" stroke-linecap="round"/>
<line x1="16" y1="-8" x2="20" y2="-20" stroke="#1e293b" stroke-width="3.5" stroke-linecap="round"/>
<polygon points="14,-22 26,-22 20,-28" fill="#1e293b"/>
</g>`)
},
{
id:'figy_csuszos',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Csúszós útburkolat',
svg: warnTriangle(`<path d="M48 44 C48 44 44 60 38 72 M52 44 C56 56 68 60 72 68" fill="none" stroke="#1e293b" stroke-width="5" stroke-linecap="round"/>
<rect x="42" y="38" width="16" height="10" rx="3" fill="#1e293b"/>`)
},
{
id:'figy_vasut',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Vasúti átjáró sorompóval',
svg: warnTriangle(`<rect x="35" y="52" width="50" height="6" rx="2" fill="#1e293b"/><rect x="35" y="62" width="50" height="6" rx="2" fill="#1e293b"/><rect x="55" y="50" width="6" height="34" rx="2" fill="#1e293b"/>`)
},
{
id:'figy_egyenetlen',cat:'figyelmez',catName:'Figyelmeztető táblák',
name:'Egyenetlen úttest',
svg: warnTriangle(`<path d="M35 75 Q45 55 55 70 Q65 85 75 65" fill="none" stroke="#1e293b" stroke-width="6" stroke-linecap="round"/>`)
},
// ===== UTASÍTÓ TÁBLÁK (8) =====
{
id:'utas_jobbra',cat:'utasito',catName:'Utasító táblák',
name:'Kötelező haladási irány jobbra',
svg: blueCircle(`<polygon points="50,45 80,60 50,75" fill="#fff"/><rect x="30" y="54" width="26" height="12" rx="2" fill="#fff"/>`)
},
{
id:'utas_balra',cat:'utasito',catName:'Utasító táblák',
name:'Kötelező haladási irány balra',
svg: blueCircle(`<polygon points="70,45 40,60 70,75" fill="#fff"/><rect x="64" y="54" width="26" height="12" rx="2" fill="#fff"/>`)
},
{
id:'utas_egyenesen',cat:'utasito',catName:'Utasító táblák',
name:'Kötelező haladási irány egyenesen',
svg: blueCircle(`<polygon points="45,42 60,22 75,42" fill="#fff"/><rect x="54" y="36" width="12" height="40" rx="2" fill="#fff"/>`)
},
{
id:'utas_korforgalom',cat:'utasito',catName:'Utasító táblák',
name:'Körforgalom',
svg: blueCircle(`<g fill="none" stroke="#fff" stroke-width="5" stroke-linecap="round">
<path d="M42 44 A20 20 0 0 1 78 56"/><path d="M78 56 A20 20 0 0 1 56 80"/><path d="M56 80 A20 20 0 0 1 38 50"/>
</g><polygon points="38,40 48,48 36,52" fill="#fff"/><polygon points="82,50 74,60 80,46" fill="#fff"/><polygon points="52,84 58,72 64,84" fill="#fff"/>`)
},
{
id:'utas_kerekpar',cat:'utasito',catName:'Utasító táblák',
name:'Kerékpárút',
svg: blueCircle(`<g transform="translate(60,62) scale(0.78)"><circle cx="0" cy="12" r="10" fill="none" stroke="#fff" stroke-width="4"/><circle cx="0" cy="-14" r="10" fill="none" stroke="#fff" stroke-width="4"/><line x1="0" y1="12" x2="0" y2="-14" stroke="#fff" stroke-width="3.5"/><line x1="0" y1="-14" x2="-8" y2="-24" stroke="#fff" stroke-width="3"/><line x1="0" y1="-14" x2="8" y2="-24" stroke="#fff" stroke-width="3"/><line x1="0" y1="-4" x2="10" y2="-10" stroke="#fff" stroke-width="3"/></g>`)
},
{
id:'utas_gyalog',cat:'utasito',catName:'Utasító táblák',
name:'Gyalogút',
svg: blueCircle(`<g transform="translate(60,52) scale(0.85)">
<circle cx="0" cy="-14" r="7" fill="#fff"/>
<line x1="0" y1="-7" x2="0" y2="18" stroke="#fff" stroke-width="5" stroke-linecap="round"/>
<line x1="-14" y1="3" x2="14" y2="3" stroke="#fff" stroke-width="5" stroke-linecap="round"/>
<line x1="0" y1="18" x2="-12" y2="38" stroke="#fff" stroke-width="5" stroke-linecap="round"/>
<line x1="0" y1="18" x2="12" y2="38" stroke="#fff" stroke-width="5" stroke-linecap="round"/>
</g>`)
},
{
id:'utas_min30',cat:'utasito',catName:'Utasító táblák',
name:'Legkisebb megengedett sebesség 30 km/h',
svg: blueCircle(`<text x="60" y="72" text-anchor="middle" font-size="36" font-weight="800" fill="#fff" font-family="Arial,sans-serif">30</text>`)
},
{
id:'utas_egyenesen_jobbra',cat:'utasito',catName:'Utasító táblák',
name:'Kötelező egyenesen vagy jobbra',
svg: blueCircle(`<polygon points="45,38 60,20 75,38" fill="#fff"/><rect x="54" y="32" width="12" height="30" rx="2" fill="#fff"/>
<polygon points="66,68 86,56 78,72" fill="#fff"/><rect x="56" y="56" width="18" height="10" rx="2" fill="#fff"/>`)
},
// ===== TÁJÉKOZTATÓ TÁBLÁK (8) =====
{
id:'taj_gyalogos',cat:'taj',catName:'Tájékoztató táblák',
name:'Gyalogos-átkelőhely',
svg: blueSquare(`<polygon points="60 24, 96 80, 24 80" fill="#fff"/>
<g transform="translate(58,48) scale(0.6)">
<circle cx="0" cy="-12" r="7" fill="#003DA5"/>
<line x1="0" y1="-5" x2="0" y2="18" stroke="#003DA5" stroke-width="5" stroke-linecap="round"/>
<line x1="-14" y1="3" x2="14" y2="3" stroke="#003DA5" stroke-width="5" stroke-linecap="round"/>
<line x1="0" y1="18" x2="-12" y2="36" stroke="#003DA5" stroke-width="5" stroke-linecap="round"/>
<line x1="0" y1="18" x2="12" y2="36" stroke="#003DA5" stroke-width="5" stroke-linecap="round"/>
</g>
<g transform="translate(35,72)"><rect x="0" y="0" width="4" height="12" fill="#003DA5"/><rect x="7" y="0" width="4" height="12" fill="#003DA5"/><rect x="14" y="0" width="4" height="12" fill="#003DA5"/><rect x="21" y="0" width="4" height="12" fill="#003DA5"/></g>`)
},
{
id:'taj_parkolas',cat:'taj',catName:'Tájékoztató táblák',
name:'Parkolás',
svg: blueSquare(`<text x="60" y="80" text-anchor="middle" font-size="60" font-weight="800" fill="#fff" font-family="Arial,sans-serif">P</text>`)
},
{
id:'taj_korhaz',cat:'taj',catName:'Tájékoztató táblák',
name:'Kórház',
svg: blueSquare(`<text x="60" y="80" text-anchor="middle" font-size="60" font-weight="800" fill="#fff" font-family="Arial,sans-serif">H</text>`)
},
{
id:'taj_egyiranyu',cat:'taj',catName:'Tájékoztató táblák',
name:'Egyirányú forgalom',
svg: blueRect(`<polygon points="76,45 100,60 76,75" fill="#fff"/><rect x="24" y="52" width="56" height="16" rx="3" fill="#fff"/>`)
},
{
id:'taj_foutvonal',cat:'taj',catName:'Tájékoztató táblák',
name:'Főútvonal',
svg: svgWrap(`<rect x="60" y="18" width="50" height="50" rx="4" fill="#FCBF16" stroke="#1e293b" stroke-width="3" transform="rotate(45,60,60)"/><rect x="60" y="28" width="36" height="36" rx="2" fill="#fff" transform="rotate(45,60,60)"/>`)
},
{
id:'taj_foutvonal_vege',cat:'taj',catName:'Tájékoztató táblák',
name:'Főútvonal vége',
svg: svgWrap(`<rect x="60" y="18" width="50" height="50" rx="4" fill="#FCBF16" stroke="#1e293b" stroke-width="3" transform="rotate(45,60,60)"/><rect x="60" y="28" width="36" height="36" rx="2" fill="#fff" transform="rotate(45,60,60)"/>
<line x1="32" y1="32" x2="88" y2="88" stroke="#1e293b" stroke-width="5"/>
<line x1="36" y1="28" x2="92" y2="84" stroke="#1e293b" stroke-width="3"/>
<line x1="28" y1="36" x2="84" y2="92" stroke="#1e293b" stroke-width="3"/>`)
},
{
id:'taj_busz',cat:'taj',catName:'Tájékoztató táblák',
name:'Autóbusz-megállóhely',
svg: blueSquare(`<rect x="24" y="42" width="72" height="36" rx="8" fill="#fff"/>
<rect x="24" y="62" width="72" height="16" rx="0" fill="#fff"/>
<circle cx="40" cy="76" r="6" fill="#003DA5"/><circle cx="80" cy="76" r="6" fill="#003DA5"/>
<rect x="28" y="48" width="16" height="12" rx="3" fill="#003DA5"/>
<rect x="48" y="48" width="16" height="12" rx="3" fill="#003DA5"/>
<rect x="68" y="48" width="16" height="12" rx="3" fill="#003DA5"/>`)
},
{
id:'taj_autopalya',cat:'taj',catName:'Tájékoztató táblák',
name:'Autópálya',
svg: svgWrap(`<rect x="8" y="16" width="104" height="88" rx="8" fill="#008751"/>
<path d="M38 88 L52 36 Q60 26 68 36 L82 88" fill="none" stroke="#fff" stroke-width="5"/>
<line x1="52" y1="50" x2="68" y2="50" stroke="#fff" stroke-width="4"/>
<path d="M30 88 Q60 50 90 88" fill="none" stroke="#fff" stroke-width="3"/>`)
}
];
// ===== QUIZ STATE =====
let selectedCat = 'all';
let selectedCount = 10;
let questions = [];
let currentQ = 0;
let score = 0;
let answered = false;
let wrongAnswers = [];
function selectCat(el){
document.querySelectorAll('.cat-pill').forEach(p=>p.classList.remove('active'));
el.classList.add('active');
selectedCat = el.dataset.cat;
}
function selectCount(el){
document.querySelectorAll('.count-btn').forEach(b=>b.classList.remove('active'));
el.classList.add('active');
selectedCount = parseInt(el.dataset.count);
}
function shuffle(arr){
const a=[...arr];
for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]]}
return a;
}
function getDistractors(correctSign, count){
// Prefer same category, then other categories
const sameCat = signs.filter(s=>s.cat===correctSign.cat && s.id!==correctSign.id);
const otherCat = signs.filter(s=>s.cat!==correctSign.cat);
const shuffledSame = shuffle(sameCat);
const shuffledOther = shuffle(otherCat);
const pool = [...shuffledSame, ...shuffledOther];
return pool.slice(0, count);
}
function startQuiz(){
let pool = selectedCat==='all' ? [...signs] : signs.filter(s=>s.cat===selectedCat);
pool = shuffle(pool);
let count = selectedCount===0 ? pool.length : Math.min(selectedCount, pool.length);
questions = pool.slice(0, count);
currentQ = 0;
score = 0;
answered = false;
wrongAnswers = [];
document.getElementById('startScreen').style.display='none';
document.getElementById('quizScreen').style.display='block';
document.getElementById('resultScreen').style.display='none';
showQuestion();
}
function showQuestion(){
answered = false;
const q = questions[currentQ];
const total = questions.length;
document.getElementById('progressBar').style.width = ((currentQ)/total*100)+'%';
document.getElementById('questionNum').textContent = `${currentQ+1} / ${total}`;
document.getElementById('scoreDisplay').textContent = `${score} pont`;
document.getElementById('signSvg').innerHTML = q.svg;
const catEl = document.getElementById('signCat');
catEl.textContent = q.catName;
catEl.className = 'sign-category ' + q.cat;
// Build answers: correct + 3 distractors
const distractors = getDistractors(q, 3);
let options = shuffle([q, ...distractors]);
const letters = ['A','B','C','D'];
const div = document.getElementById('answersDiv');
div.innerHTML = '';
options.forEach((opt,i) => {
const btn = document.createElement('button');
btn.className = 'answer-btn';
btn.innerHTML = `<span class="letter">${letters[i]}</span><span>${opt.name}</span>`;
btn.onclick = () => handleAnswer(btn, opt.id === q.id, q, opt);
div.appendChild(btn);
});
document.getElementById('nextBtn').classList.remove('visible');
// Fade in
const card = document.getElementById('signCard');
card.classList.remove('fade-out');
card.classList.add('fade-in');
requestAnimationFrame(()=>{requestAnimationFrame(()=>{card.classList.remove('fade-in')})});
}
function handleAnswer(btn, isCorrect, question, chosen){
if(answered) return;
answered = true;
const allBtns = document.querySelectorAll('.answer-btn');
allBtns.forEach(b => {
b.classList.add('disabled');
// Reveal correct answer
if(b.querySelector('span:last-child').textContent === question.name){
b.classList.add('reveal-correct');
}
});
if(isCorrect){
btn.classList.remove('reveal-correct');
btn.classList.add('correct');
score++;
document.getElementById('scoreDisplay').textContent = `${score} pont`;
} else {
btn.classList.add('wrong');
wrongAnswers.push({question, chosenName: chosen.name});
}
document.getElementById('nextBtn').classList.add('visible');
}
function nextQuestion(){
currentQ++;
if(currentQ >= questions.length){
showResult();
return;
}
const card = document.getElementById('signCard');
card.classList.add('fade-out');
setTimeout(()=>{showQuestion()}, 200);
}
function showResult(){
document.getElementById('quizScreen').style.display='none';
document.getElementById('resultScreen').style.display='block';
const total = questions.length;
const pct = Math.round(score/total*100);
const wrong = total - score;
// Donut
const donut = document.getElementById('donutChart');
const green = '#16a34a';
const red = '#ef4444';
const gray = '#e2e8f0';
const correctDeg = pct * 3.6;
donut.style.background = `conic-gradient(${green} 0deg ${correctDeg}deg, ${red} ${correctDeg}deg 360deg)`;
if(total===0) donut.style.background = gray;
document.getElementById('pctText').textContent = pct + '%';
document.getElementById('statCorrect').textContent = score;
document.getElementById('statTotal').textContent = total;
document.getElementById('statWrong').textContent = wrong;
let msg, sub, color;
if(pct >= 90){ msg='Kiváló eredmény!'; sub='Szinte hibátlan, gratulálok!'; color='#16a34a'; }
else if(pct >= 70){ msg='Jó eredmény!'; sub='Még egy kis gyakorlás és tökéletes lesz.'; color='#3b82f6'; }
else if(pct >= 50){ msg='Elfogadható.'; sub='Érdemes átismételni a táblákat.'; color='#f59e0b'; }
else { msg='Gyenge eredmény.'; sub='Több gyakorlásra van szükség!'; color='#ef4444'; }
document.getElementById('resultMsg').textContent = msg;
document.getElementById('resultMsg').style.color = color;
document.getElementById('resultSub').textContent = sub;
document.getElementById('pctText').style.color = color;
// Wrong answers review
const reviewDiv = document.getElementById('wrongReview');
if(wrongAnswers.length > 0){
let html = '<h3>Hibás válaszok áttekintése</h3>';
wrongAnswers.forEach(w => {
html += `<div class="wrong-item">
${w.question.svg.replace('viewBox=','style="width:56px;height:56px" viewBox=')}
<div class="wrong-detail">
<div class="correct-ans">Helyes: ${w.question.name}</div>
<div class="your-ans">Te válaszod: ${w.chosenName}</div>
</div>
</div>`;
});
reviewDiv.innerHTML = html;
} else {
reviewDiv.innerHTML = '<h3 style="text-align:center;color:#16a34a">Hibátlan! Egyetlen hibás válasz sem volt.</h3>';
}
// Animate progress bar to 100%
document.getElementById('progressBar').style.width = '100%';
}
function restartQuiz(){
document.getElementById('startScreen').style.display='block';
document.getElementById('quizScreen').style.display='none';
document.getElementById('resultScreen').style.display='none';
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment