Four_Colors / index.html
eaglelandsonce's picture
Update index.html
af1d45a verified
raw
history blame
30.7 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Four Colors Personality — 40Q (Blind Choices)</title>
<style>
:root{
--red:#e63946;
--yellow:#f4d35e;
--green:#2a9d8f;
--blue:#4361ee;
--bg:#0b1020;
--card:#11172b;
--card-2:#0f1527;
--ring:#334155;
--white:#f8fafc;
}
*{box-sizing:border-box}
body{
margin:0; font-family:ui-sans-serif,system-ui,Segoe UI,Roboto,Helvetica,Arial;
color:var(--white); background: radial-gradient(1200px 800px at 70% -10%, #17203a 0%, #0b1020 60%) fixed;
}
header{
padding:24px 18px; text-align:center;
background:linear-gradient(90deg,var(--red),var(--yellow),var(--green),var(--blue));
-webkit-background-clip:text; background-clip:text; color:transparent; font-weight:800; letter-spacing:.3px;
font-size: clamp(22px, 3.4vw, 36px);
}
.sub{color:#cbd5e1; text-align:center; margin:-8px 0 10px 0; font-size:14px}
.wrap{max-width:980px; margin:0 auto; padding:16px}
.card{
background: linear-gradient(180deg, var(--card) 0%, var(--card-2) 100%);
border:1px solid #1f2a44; border-radius:18px; box-shadow: 0 10px 30px rgba(0,0,0,.25);
}
.center{display:flex; align-items:center; justify-content:center}
.btn{
border:none; cursor:pointer; padding:12px 16px; border-radius:12px; font-weight:700;
background:#1f2b49; color:#e2e8f0; transition:transform .05s ease, box-shadow .2s ease, background .2s ease;
box-shadow:0 6px 16px rgba(0,0,0,.25);
}
.btn:hover{background:#243257}
.btn:active{transform:translateY(1px)}
.btn.primary{background:linear-gradient(90deg,#3b82f6,#06b6d4)}
.btn.primary:hover{filter:brightness(1.05)}
.row{display:flex; gap:12px; flex-wrap:wrap}
/* Intro */
#intro{padding:28px}
.hero{padding:20px; text-align:center;}
.hero p{color:#cbd5e1}
.grid{display:grid; gap:12px; grid-template-columns:1fr; margin-top:14px}
@media (min-width:780px){ .grid{grid-template-columns:repeat(2,1fr)} }
.info{
padding:14px; border:1px solid #243055; border-radius:14px; background:#0e1530; color:#dbeafe; text-align:left;
}
.info h3{margin:6px 0 4px 0; font-size:16px}
.info p{margin:4px 0 0 0; font-size:14px; color:#cbd5e1}
.legend{display:grid; grid-template-columns:1fr; gap:10px; margin-top:14px}
@media (min-width:720px){ .legend{grid-template-columns:repeat(4,1fr)} }
.chip{
border:1px solid #223058; border-radius:14px; padding:10px; background:#0f152c; color:#e5e7eb;
}
.chip .t{font-weight:800}
.chip .s{font-size:12px; color:#cbd5e1; margin-top:4px}
/* Quiz */
#quiz{padding:16px}
.topbar{padding:16px; border-bottom:1px solid #1e293b; display:flex; align-items:center; gap:14px}
.pill{
padding:6px 10px; border-radius:999px; font-size:12px; background:#0d1326; border:1px solid #1e2742; color:#d1d5db
}
.progress{
position:relative; height:12px; width:100%; background:#0b1224; border:1px solid #1e2742; border-radius:999px; overflow:hidden;
}
.bar{height:100%; width:0%; background:linear-gradient(90deg,var(--red),var(--yellow),var(--green),var(--blue)); transition:width .25s ease}
.qwrap{padding:22px}
.qnum{font-size:13px; color:#93a3c6; margin-bottom:6px}
.qtext{font-size:20px; line-height:1.4; font-weight:700; color:#e6edf7}
.options{margin-top:14px; display:grid; gap:12px}
.opt{
text-align:left; padding:14px 16px; border-radius:14px; border:1px solid #1f2a44; background:#0f1527; color:#e2e8f0;
cursor:pointer; position:relative; isolation:isolate; transition:transform .04s ease, border-color .2s ease, background .2s ease;
}
.opt:hover{transform:translateY(-1px); border-color:#2b3a60; background:#131a33}
.opt[selected]{outline:2px solid var(--ring)}
.foot{display:flex; justify-content:space-between; align-items:center; padding:16px; border-top:1px solid #1e293b}
.muted{color:#94a3b8; font-size:12px}
/* Results */
#result{padding:18px}
.scoregrid{display:grid; grid-template-columns:1fr; gap:14px}
@media (min-width:720px){ .scoregrid{grid-template-columns:1fr 1fr} }
.score{
padding:14px; border:1px solid #1f2a44; border-radius:16px; background:#0f1527;
}
.shead{display:flex; gap:10px; align-items:center; justify-content:space-between}
.sname{font-weight:900; letter-spacing:.2px}
.sval{font-variant-numeric:tabular-nums}
.barwrap{height:12px; background:#0b1224; border:1px solid #1e2742; border-radius:999px; overflow:hidden; margin-top:10px}
.barinner{height:100%; width:0%; transition:width .6s ease}
.r{background:var(--red)} .y{background:var(--yellow)} .g{background:var(--green)} .b{background:var(--blue)}
.callout{
margin-top:16px; padding:14px; border:1px dashed #334155; border-radius:14px; background:#0c1226; color:#cbd5e1
}
.badges{display:flex; gap:8px; flex-wrap:wrap; margin-top:6px}
.badge{
padding:6px 10px; border-radius:999px; border:1px solid #223058; background:#0e1530; color:#dbeafe; font-size:12px; font-weight:700;
}
/* Tiny confetti */
.confetti{position:fixed; inset:0; pointer-events:none}
</style>
</head>
<body>
<header>Four Colors Personality — 40-Question Assessment</header>
<div class="sub">Discover your blend across four complementary styles</div>
<div class="wrap">
<!-- INTRO -->
<section id="intro" class="card">
<div class="hero">
<h2 style="margin:10px 0 6px 0;">Find your color mix in ~6 minutes</h2>
<p>Answer 40 quick scenario questions. Options are <b>blind-labeled</b> (no color hints) to reduce bias. At the end you’ll see your score profile across the four styles with tips to interpret it.</p>
<div class="grid">
<div class="info">
<h3>About the Four Colors</h3>
<p>This framework groups common behavior and communication preferences into four styles. You’re not one color—you’re a <b>blend</b>. Your scores show what you tend to use most, not what you’re capable of.</p>
<div class="legend" aria-hidden="true">
<div class="chip">
<div class="t">🔴 Red — Leader/Director</div>
<div class="s">Decisive, goal-oriented • Focus: results • Watch-out: impatience</div>
</div>
<div class="chip">
<div class="t">🟡 Yellow — Socializer/Inspirer</div>
<div class="s">Energetic, persuasive • Focus: people & momentum • Watch-out: follow-through</div>
</div>
<div class="chip">
<div class="t">🟢 Green — Nurturer/Supporter</div>
<div class="s">Patient, dependable • Focus: harmony & trust • Watch-out: avoiding conflict</div>
</div>
<div class="chip">
<div class="t">🔵 Blue — Thinker/Analyzer</div>
<div class="s">Analytical, thorough • Focus: quality & accuracy • Watch-out: over-perfection</div>
</div>
</div>
</div>
<div class="info">
<h3>How scoring works</h3>
<p>Each question has four options. Picking an option gives its hidden category <b>1 point</b>. After 40 questions we total points per category and show counts and percentages.</p>
</div>
</div>
<div class="row center" style="margin-top:14px">
<button id="startBtn" class="btn primary">Start the quiz</button>
<button id="howBtn" class="btn" title="Toggle quick notes">Quick notes</button>
</div>
<div id="howText" style="display:none; margin-top:12px; color:#cbd5e1;">
Blind choices (no color cues) • 40 questions • 1 point per selected option • results show totals and %.
</div>
<div class="badges" style="justify-content:center;margin-top:12px">
<span class="badge">Bias-reduced options</span>
<span class="badge">Back/Next navigation</span>
<span class="badge">CSV download</span>
</div>
</div>
</section>
<!-- QUIZ -->
<section id="quiz" class="card" hidden>
<div class="topbar">
<div class="pill" id="counter">Q 1 / 40</div>
<div class="progress"><div class="bar" id="pbar"></div></div>
<div class="pill" id="answeredPill">Answered: 0</div>
</div>
<div class="qwrap">
<div class="qnum" id="qnum">Question 1</div>
<div class="qtext" id="qtext">Loading…</div>
<div class="options" id="opts"></div>
</div>
<div class="foot">
<div class="muted">Tip: You can change answers anytime.</div>
<div class="row">
<button class="btn" id="prevBtn">◀ Back</button>
<button class="btn primary" id="nextBtn">Next ▶</button>
<button class="btn" id="submitBtn" style="display:none">See results 🎉</button>
</div>
</div>
</section>
<!-- RESULTS -->
<section id="result" class="card" hidden>
<div class="hero" style="padding:16px 16px 8px 16px">
<h2 style="margin:6px 0 0 0">Your Four-Color Profile</h2>
<p class="muted" id="summaryLine">Here’s your distribution across the four styles.</p>
</div>
<div class="qwrap">
<div class="scoregrid" id="scoreGrid"></div>
<div class="callout" id="interpretation">
<b>How to read your results</b>
<ul style="margin:8px 0 0 18px">
<li><b>Dominant</b>: your most natural style—lean into it for momentum.</li>
<li><b>Secondary</b>: your reliable backup—blend with dominant for versatility.</li>
<li><b>Balance</b>: closer scores → easier style-switching; wider gaps → clearer preferences.</li>
<li><b>Growth tips</b>: Low 🔵? Add structure/checklists. Low 🟢? Practice active listening. Low 🔴? Set bolder targets. Low 🟡? Invite more brainstorming.</li>
</ul>
</div>
<div class="callout" id="dominants" style="margin-top:12px"></div>
<div class="row" style="margin-top:12px">
<button class="btn" id="downloadBtn">Download CSV</button>
<button class="btn" id="restartBtn">Restart</button>
</div>
</div>
</section>
</div>
<canvas class="confetti" id="confetti"></canvas>
<script>
/* ========= Color dictionary ========= */
const COLORS = {
R: { key:'R', name:'Red — Leader / Director', emoji:'🔴',
strengths:'Assertive, decisive, goal-oriented, confident.',
focus:'Results and control.',
style:'Direct, action-driven, competitive.',
challenges:'May be seen as domineering or impatient.' },
Y: { key:'Y', name:'Yellow — Socializer / Inspirer', emoji:'🟡',
strengths:'Energetic, outgoing, persuasive, enthusiastic.',
focus:'Fun, recognition, relationships.',
style:'Optimistic, talkative, spontaneous.',
challenges:'May struggle with details or consistency.' },
G: { key:'G', name:'Green — Nurturer / Supporter', emoji:'🟢',
strengths:'Loyal, caring, patient, dependable.',
focus:'Harmony, relationships, security.',
style:'Good listener, cooperative, empathetic.',
challenges:'Can resist change or avoid conflict.' },
B: { key:'B', name:'Blue — Thinker / Analyzer', emoji:'🔵',
strengths:'Analytical, detail-oriented, disciplined, cautious.',
focus:'Accuracy, structure, logic.',
style:'Organized, thorough, systematic.',
challenges:'May be overly critical or slow to act.' }
};
/* ========= Question bank (40) =========
Each option maps to a hidden color: R, Y, G, or B.
UI shows NO color hints to the participant.
*/
const Q = [
{ q: 'Kicking off a new project, I first…',
o: [
{t:'Clarify the goal and decide who does what.', c:'R'},
{t:'Create buzz and get everyone excited.', c:'Y'},
{t:'Ensure everyone feels included and supported.', c:'G'},
{t:'Outline a structured plan and milestones.', c:'B'}
]},
{ q: 'In meetings I typically…',
o: [
{t:'Drive decisions and move to action.', c:'R'},
{t:'Keep energy high and engage people.', c:'Y'},
{t:'Listen carefully and build consensus.', c:'G'},
{t:'Take notes, analyze details, ask clarifying questions.', c:'B'}
]},
{ q: 'With a tight deadline, I…',
o: [
{t:'Take charge and push hard to finish.', c:'R'},
{t:'Rally the team’s spirits to keep momentum.', c:'Y'},
{t:'Check in on everyone’s workload and stress.', c:'G'},
{t:'Prioritize tasks methodically and track progress.', c:'B'}
]},
{ q: 'When conflict arises, I…',
o: [
{t:'Address it directly and resolve quickly.', c:'R'},
{t:'Defuse with humor and positivity.', c:'Y'},
{t:'Mediate gently so all feel heard.', c:'G'},
{t:'Examine facts and find a logical solution.', c:'B'}
]},
{ q: 'Learning something new, I prefer…',
o: [
{t:'Hands-on doing and quick wins.', c:'R'},
{t:'Interactive, fun sessions with others.', c:'Y'},
{t:'Supportive pace with time to ask questions.', c:'G'},
{t:'Clear documentation and step-by-step guides.', c:'B'}
]},
{ q: 'Giving feedback, I am…',
o: [
{t:'Direct and to the point.', c:'R'},
{t:'Encouraging and motivational.', c:'Y'},
{t:'Kind, private, and considerate.', c:'G'},
{t:'Specific, evidence-based, and precise.', c:'B'}
]},
{ q: 'Receiving feedback, I want…',
o: [
{t:'Actionable suggestions to improve fast.', c:'R'},
{t:'Positive tone and recognition of strengths.', c:'Y'},
{t:'Empathy and a supportive conversation.', c:'G'},
{t:'Clear examples and data behind it.', c:'B'}
]},
{ q: 'Planning approach:',
o: [
{t:'Set bold targets and go.', c:'R'},
{t:'Explore ideas creatively with others.', c:'Y'},
{t:'Coordinate people and keep harmony.', c:'G'},
{t:'Build a structured, detailed roadmap.', c:'B'}
]},
{ q: 'Handling change, I…',
o: [
{t:'Lead the charge and adapt quickly.', c:'R'},
{t:'See opportunity and hype the upside.', c:'Y'},
{t:'Support people through the transition.', c:'G'},
{t:'Assess risks and create a stable plan.', c:'B'}
]},
{ q: 'Brainstorming style:',
o: [
{t:'Decide fast which ideas are viable.', c:'R'},
{t:'Generate lots of wild ideas.', c:'Y'},
{t:'Encourage quieter voices to share.', c:'G'},
{t:'Evaluate feasibility and constraints.', c:'B'}
]},
{ q: 'After brainstorming, I…',
o: [
{t:'Assign owners and timelines.', c:'R'},
{t:'Keep enthusiasm high for execution.', c:'Y'},
{t:'Align the team on roles and support needs.', c:'G'},
{t:'Create specs and acceptance criteria.', c:'B'}
]},
{ q: 'When details matter, I…',
o: [
{t:'Focus only on the critical few.', c:'R'},
{t:'Ask others to help track them.', c:'Y'},
{t:'Check in to ensure no one is stuck.', c:'G'},
{t:'Dive into the fine print thoroughly.', c:'B'}
]},
{ q: 'Networking at events, I…',
o: [
{t:'Make strategic connections quickly.', c:'R'},
{t:'Meet many people and keep it lively.', c:'Y'},
{t:'Have meaningful one-on-one chats.', c:'G'},
{t:'Prepare targeted questions and follow up precisely.', c:'B'}
]},
{ q: 'Dealing with risk, I…',
o: [
{t:'Make bold calls and accept responsibility.', c:'R'},
{t:'Bet on possibilities and momentum.', c:'Y'},
{t:'Seek consensus and minimize stress.', c:'G'},
{t:'Model scenarios and mitigate systematically.', c:'B'}
]},
{ q: 'Routine tasks, I…',
o: [
{t:'Streamline or delegate to move faster.', c:'R'},
{t:'Make them social or fun.', c:'Y'},
{t:'Do them reliably and help others.', c:'G'},
{t:'Create checklists and optimize process.', c:'B'}
]},
{ q: 'Choosing a new tool, I…',
o: [
{t:'Pick what gets results now.', c:'R'},
{t:'Choose what the team enjoys using.', c:'Y'},
{t:'Consider impact on people and support.', c:'G'},
{t:'Compare specs and read reviews deeply.', c:'B'}
]},
{ q: 'Delegation preference:',
o: [
{t:'Assign stretch goals with autonomy.', c:'R'},
{t:'Match tasks to interests/energy.', c:'Y'},
{t:'Balance workload and provide help.', c:'G'},
{t:'Match tasks to skills and precision.', c:'B'}
]},
{ q: 'Crisis response:',
o: [
{t:'Take command and act immediately.', c:'R'},
{t:'Keep everyone calm and optimistic.', c:'Y'},
{t:'Check safety and support needs.', c:'G'},
{t:'Diagnose root cause before acting.', c:'B'}
]},
{ q: 'Writing emails, I am…',
o: [
{t:'Short and directive.', c:'R'},
{t:'Warm and personable.', c:'Y'},
{t:'Thoughtful and encouraging.', c:'G'},
{t:'Clear and detailed.', c:'B'}
]},
{ q: 'Decision-making style:',
o: [
{t:'Decide fast and adjust later.', c:'R'},
{t:'Gather input broadly.', c:'Y'},
{t:'Seek consensus where possible.', c:'G'},
{t:'Decide after careful analysis.', c:'B'}
]},
{ q: 'Time management:',
o: [
{t:'Prioritize and push through blocks.', c:'R'},
{t:'Follow energy and collaboration windows.', c:'Y'},
{t:'Plan around people’s needs.', c:'G'},
{t:'Schedule meticulously with buffers.', c:'B'}
]},
{ q: 'Most motivating to me:',
o: [
{t:'Winning and achieving bold goals.', c:'R'},
{t:'Recognition and shared excitement.', c:'Y'},
{t:'Helping others and belonging.', c:'G'},
{t:'Mastery, accuracy, and clarity.', c:'B'}
]},
{ q: 'Leadership vibe:',
o: [
{t:'Commanding and decisive.', c:'R'},
{t:'Inspiring and upbeat.', c:'Y'},
{t:'Supportive and steady.', c:'G'},
{t:'Thoughtful and thorough.', c:'B'}
]},
{ q: 'Collaboration style:',
o: [
{t:'Drive outcomes, remove blockers.', c:'R'},
{t:'Spark ideas and energy.', c:'Y'},
{t:'Facilitate teamwork and trust.', c:'G'},
{t:'Bring structure and rigor.', c:'B'}
]},
{ q: 'Data vs. intuition:',
o: [
{t:'Go with informed instinct.', c:'R'},
{t:'Trust vibe and momentum.', c:'Y'},
{t:'Ask people and feel the mood.', c:'G'},
{t:'Lean on data and models.', c:'B'}
]},
{ q: 'On a brand-new team, I…',
o: [
{t:'Set direction and clarify roles.', c:'R'},
{t:'Break the ice and build rapport.', c:'Y'},
{t:'Ensure everyone feels included.', c:'G'},
{t:'Define process and standards.', c:'B'}
]},
{ q: 'Rules and processes, I…',
o: [
{t:'Bypass if they slow results.', c:'R'},
{t:'Adapt them to fit the moment.', c:'Y'},
{t:'Respect them to keep peace.', c:'G'},
{t:'Follow them to ensure quality.', c:'B'}
]},
{ q: 'Innovation to me is…',
o: [
{t:'Bold moves that change the game.', c:'R'},
{t:'Creative sparks from people connecting.', c:'Y'},
{t:'Improvements that help the group.', c:'G'},
{t:'Disciplined experiments that work.', c:'B'}
]},
{ q: 'I feel drained by…',
o: [
{t:'Slow indecision.', c:'R'},
{t:'Long solitary detail work.', c:'Y'},
{t:'Harsh conflict.', c:'G'},
{t:'Chaotic, unstructured demands.', c:'B'}
]},
{ q: 'I feel energized by…',
o: [
{t:'Challenging goals.', c:'R'},
{t:'Lively collaboration.', c:'Y'},
{t:'Helping others succeed.', c:'G'},
{t:'Solving complex puzzles.', c:'B'}
]},
{ q: 'Preferred workspace:',
o: [
{t:'Efficient, focused, outcome-oriented.', c:'R'},
{t:'Open, lively, with people around.', c:'Y'},
{t:'Calm, friendly, supportive.', c:'G'},
{t:'Quiet, organized, minimal interruptions.', c:'B'}
]},
{ q: 'Preferred communication:',
o: [
{t:'Direct and brief.', c:'R'},
{t:'Casual and upbeat.', c:'Y'},
{t:'Kind and considerate.', c:'G'},
{t:'Detailed and clear.', c:'B'}
]},
{ q: 'Handling ambiguity:',
o: [
{t:'Make a call and iterate.', c:'R'},
{t:'Explore options with others.', c:'Y'},
{t:'Stabilize people, then decide.', c:'G'},
{t:'Define terms and reduce unknowns.', c:'B'}
]},
{ q: 'Goal setting:',
o: [
{t:'Stretch targets, big wins.', c:'R'},
{t:'Goals that inspire people.', c:'Y'},
{t:'Shared goals the team supports.', c:'G'},
{t:'SMART goals with metrics.', c:'B'}
]},
{ q: 'Measuring success:',
o: [
{t:'Did we deliver the outcome?', c:'R'},
{t:'Is the team engaged?', c:'Y'},
{t:'Are people satisfied and safe?', c:'G'},
{t:'Do metrics show quality?', c:'B'}
]},
{ q: 'Handling mistakes:',
o: [
{t:'Own it, fix it, move on.', c:'R'},
{t:'Keep spirits up and try again.', c:'Y'},
{t:'Support those affected.', c:'G'},
{t:'Analyze root cause and prevent repeat.', c:'B'}
]},
{ q: 'Others value me for…',
o: [
{t:'Getting things done.', c:'R'},
{t:'Bringing positivity.', c:'Y'},
{t:'Being dependable and kind.', c:'G'},
{t:'Accuracy and clear thinking.', c:'B'}
]},
{ q: 'I’m most frustrated by…',
o: [
{t:'Lack of ownership.', c:'R'},
{t:'Negativity and boredom.', c:'Y'},
{t:'Conflict and rudeness.', c:'G'},
{t:'Sloppiness and vagueness.', c:'B'}
]},
{ q: 'Weekend style (analogy):',
o: [
{t:'Plan a mission and execute.', c:'R'},
{t:'Gather friends for something fun.', c:'Y'},
{t:'Quality time with close people.', c:'G'},
{t:'Tinker, read, or learn a system.', c:'B'}
]},
{ q: 'Teaching others, I…',
o: [
{t:'Set targets and push for outcomes.', c:'R'},
{t:'Make it lively and engaging.', c:'Y'},
{t:'Be patient and supportive.', c:'G'},
{t:'Explain steps clearly and precisely.', c:'B'}
]}
];
/* ========= State ========= */
const totalQ = Q.length; // 40
let idx = 0;
let answers = Array(totalQ).fill(null); // 'R'|'Y'|'G'|'B' or null
/* ========= DOM hooks ========= */
const introEl = document.getElementById('intro');
const quizEl = document.getElementById('quiz');
const resEl = document.getElementById('result');
const startBtn = document.getElementById('startBtn');
const howBtn = document.getElementById('howBtn');
const howText = document.getElementById('howText');
const pbar = document.getElementById('pbar');
const qnum = document.getElementById('qnum');
const qtext = document.getElementById('qtext');
const opts = document.getElementById('opts');
const counter = document.getElementById('counter');
const answeredPill = document.getElementById('answeredPill');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const submitBtn = document.getElementById('submitBtn');
const scoreGrid = document.getElementById('scoreGrid');
const summaryLine = document.getElementById('summaryLine');
const dominants = document.getElementById('dominants');
const restartBtn = document.getElementById('restartBtn');
const downloadBtn = document.getElementById('downloadBtn');
/* ========= Helpers ========= */
function shuffle(arr){
const a = arr.slice();
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 answeredCount(){ return answers.filter(x=>x!==null).length; }
function updateProgress(){
const pct = (answeredCount()/totalQ)*100;
pbar.style.width = pct.toFixed(1)+'%';
counter.textContent = `Q ${idx+1} / ${totalQ}`;
answeredPill.textContent = `Answered: ${answeredCount()}`;
prevBtn.disabled = idx===0;
if(idx===totalQ-1){
nextBtn.style.display='none';
submitBtn.style.display='inline-block';
submitBtn.disabled = (answers[idx]===null);
}else{
nextBtn.style.display='inline-block';
submitBtn.style.display='none';
nextBtn.disabled = (answers[idx]===null);
}
}
function renderQuestion(){
const item = Q[idx];
qnum.textContent = `Question ${idx+1}`;
qtext.textContent = item.q;
// Randomize option order each render for fairness (still blind)
const options = shuffle(item.o.map((o, i)=>({...o, i})));
opts.innerHTML = '';
options.forEach((opt, k)=>{
const btn = document.createElement('button');
btn.className='opt';
btn.setAttribute('data-color', opt.c); // hidden mapping
btn.setAttribute('aria-label', `Option ${k+1}`); // neutral label
btn.textContent = opt.t; // NO emojis, NO color tags
btn.addEventListener('click', ()=>{
answers[idx] = opt.c;
Array.from(opts.children).forEach(c=>c.removeAttribute('selected'));
btn.setAttribute('selected','');
updateProgress();
});
if(answers[idx]===opt.c){ btn.setAttribute('selected',''); }
opts.appendChild(btn);
});
updateProgress();
}
function computeScores(){
const scores = {R:0,Y:0,G:0,B:0};
answers.forEach(a=>{ if(a) scores[a]++; });
const total = Object.values(scores).reduce((s,v)=>s+v,0);
const pct = Object.fromEntries(Object.entries(scores).map(([k,v])=>[k, total? (v*100/total):0 ]));
return {scores, pct, total};
}
/* ========= Results rendering ========= */
function labelFor(c){ return ({R:'🔴',Y:'🟡',G:'🟢',B:'🔵'})[c] || ''; }
function renderResults(){
const {scores, pct, total} = computeScores();
const sorted = Object.entries(scores).sort((a,b)=>b[1]-a[1]);
const [domKey, secKey] = [sorted[0][0], sorted[1][0]];
summaryLine.innerHTML =
`Answered <b>${total}</b> of ${totalQ}. Dominant: <b>${labelFor(domKey)} ${COLORS[domKey].name}</b>. Secondary: <b>${labelFor(secKey)} ${COLORS[secKey].name}</b>.`;
scoreGrid.innerHTML = '';
['R','Y','G','B'].forEach(k=>{
const card = document.createElement('div');
card.className='score';
const pctStr = pct[k].toFixed(0)+'%';
card.innerHTML = `
<div class="shead">
<div class="sname">${labelFor(k)} ${COLORS[k].name}</div>
<div class="sval"><b>${scores[k]}</b> / ${total} &nbsp; <span class="muted">(${pctStr})</span></div>
</div>
<div class="barwrap"><div class="barinner ${k.toLowerCase()}" style="width:${pct[k]}%"></div></div>
<div style="margin-top:10px; color:#cbd5e1; font-size:14px">
<b>Strengths:</b> ${COLORS[k].strengths}<br/>
<b>Focus:</b> ${COLORS[k].focus}<br/>
<b>Style:</b> ${COLORS[k].style}<br/>
<b>Watch-outs:</b> ${COLORS[k].challenges}
</div>
`;
scoreGrid.appendChild(card);
});
dominants.innerHTML = `
<b>Your blend:</b> ${labelFor(domKey)} <b>${COLORS[domKey].name.split('—')[0].trim()}</b> with
${labelFor(secKey)} <b>${COLORS[secKey].name.split('—')[0].trim()}</b> as a secondary.
<div class="badges" style="margin-top:8px">
<span class="badge">🔴 Results</span>
<span class="badge">🟡 Energy</span>
<span class="badge">🟢 Harmony</span>
<span class="badge">🔵 Structure</span>
</div>
<div style="margin-top:8px; color:#cbd5e1">
Try flexing your lower-scoring colors when situations call for them (e.g., add structure for 🔵, add empathy for 🟢, add drive for 🔴, add spark for 🟡).
</div>
`;
burstConfetti();
}
/* ========= Confetti ========= */
const confettiCanvas = document.getElementById('confetti');
const ctx = confettiCanvas.getContext('2d');
let confettiBits = [];
function resizeCanvas(){
confettiCanvas.width = window.innerWidth;
confettiCanvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas); resizeCanvas();
function burstConfetti(){
const colors = ['#e63946','#f4d35e','#2a9d8f','#4361ee'];
const pieces = 160;
confettiBits = [];
for(let i=0;i<pieces;i++){
confettiBits.push({
x: confettiCanvas.width/2,
y: confettiCanvas.height/3,
r: 2+Math.random()*4,
vx: (Math.random()-0.5)*6,
vy: -3 - Math.random()*5,
g: 0.09 + Math.random()*0.05,
a: 1,
c: colors[i%colors.length],
rot: Math.random()*Math.PI,
vr: (Math.random()-0.5)*0.2
});
}
animateConfetti(0);
}
function animateConfetti(){
ctx.clearRect(0,0,confettiCanvas.width,confettiCanvas.height);
confettiBits.forEach(p=>{
p.x += p.vx;
p.y += p.vy;
p.vy += p.g;
p.rot += p.vr;
p.a -= 0.008;
ctx.globalAlpha = Math.max(p.a,0);
ctx.fillStyle = p.c;
ctx.save();
ctx.translate(p.x, p.y);
ctx.rotate(p.rot);
ctx.fillRect(-p.r, -p.r, p.r*2, p.r*2);
ctx.restore();
});
ctx.globalAlpha = 1;
confettiBits = confettiBits.filter(p=>p.a>0 && p.y<confettiCanvas.height+20);
if(confettiBits.length>0) requestAnimationFrame(animateConfetti);
}
/* ========= Navigation & events ========= */
function show(el){ el.hidden=false; }
function hide(el){ el.hidden=true; }
startBtn.addEventListener('click', ()=>{
hide(introEl); show(quizEl);
idx = 0; answers.fill(null);
renderQuestion();
});
howBtn.addEventListener('click', ()=> howText.style.display = howText.style.display==='none' ? 'block' : 'none');
prevBtn.addEventListener('click', ()=>{
if(idx>0){ idx--; renderQuestion(); }
});
nextBtn.addEventListener('click', ()=>{
if(answers[idx]===null){ shake(opts); return; }
if(idx<totalQ-1){ idx++; renderQuestion(); }
});
submitBtn.addEventListener('click', ()=>{
if(answers[idx]===null){ shake(opts); return; }
hide(quizEl); show(resEl);
renderResults();
});
restartBtn.addEventListener('click', ()=>{
hide(resEl); show(introEl);
window.scrollTo({top:0, behavior:'smooth'});
});
downloadBtn.addEventListener('click', ()=>{
const {scores, pct, total} = computeScores();
let csv = 'Question,ChosenOptionColor\n';
Q.forEach((q,i)=>{ csv += `"${q.q.replace(/"/g,'""')}",${answers[i]||''}\n`; });
csv += '\nColor,Count,Percent\n';
for(const k of ['R','Y','G','B']){
csv += `${k},${scores[k]},${pct[k].toFixed(1)}%\n`;
}
const blob = new Blob([csv], {type:'text/csv;charset=utf-8;'});
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'four_colors_results.csv';
a.click();
URL.revokeObjectURL(a.href);
});
function shake(el){
el.style.transition='transform .08s';
el.style.transform='translateX(4px)';
setTimeout(()=>{el.style.transform='translateX(-4px)';},80);
setTimeout(()=>{el.style.transform='translateX(0)';},160);
}
</script>
</body>
</html>