Spaces:
Running
Running
<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} <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> | |