Skip to content

Commit 7336a0a

Browse files
Create mbti.html
1 parent 212f978 commit 7336a0a

1 file changed

Lines changed: 326 additions & 0 deletions

File tree

public/mbti.html

Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>MBTI Personality Test</title>
7+
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,300;0,6..72,400;0,6..72,500;1,6..72,400&family=DM+Mono:wght@300;400&display=swap" rel="stylesheet">
8+
<style>
9+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
10+
body {
11+
min-height: 100vh;
12+
background: #1a1613;
13+
color: #e8e4df;
14+
font-family: 'Newsreader', Georgia, serif;
15+
display: flex;
16+
align-items: center;
17+
justify-content: center;
18+
padding: 40px 20px;
19+
}
20+
#app {
21+
max-width: 640px;
22+
width: 100%;
23+
transition: opacity 0.3s ease, transform 0.3s ease;
24+
}
25+
.fade-out { opacity: 0; transform: translateY(12px); }
26+
.fade-in { opacity: 1; transform: translateY(0); }
27+
28+
.mono { font-family: 'DM Mono', monospace; }
29+
.label {
30+
font-family: 'DM Mono', monospace;
31+
font-size: 11px;
32+
letter-spacing: 0.2em;
33+
color: #6b6560;
34+
text-transform: uppercase;
35+
text-align: center;
36+
margin-bottom: 40px;
37+
}
38+
h1.intro-title {
39+
font-size: 48px;
40+
font-weight: 300;
41+
line-height: 1.15;
42+
letter-spacing: -0.02em;
43+
text-align: center;
44+
margin-bottom: 24px;
45+
}
46+
.intro-desc {
47+
font-size: 17px;
48+
line-height: 1.7;
49+
color: #9e9590;
50+
max-width: 460px;
51+
margin: 0 auto 48px;
52+
font-weight: 300;
53+
text-align: center;
54+
}
55+
.btn-begin, .btn-retake {
56+
display: inline-block;
57+
background: transparent;
58+
border: 1px solid #4a4035;
59+
color: #c9a87c;
60+
font-family: 'DM Mono', monospace;
61+
font-size: 13px;
62+
letter-spacing: 0.12em;
63+
text-transform: uppercase;
64+
padding: 16px 48px;
65+
cursor: pointer;
66+
transition: all 0.2s ease;
67+
}
68+
.btn-begin:hover { border-color: #c9a87c; background: rgba(201,168,124,0.06); }
69+
.btn-retake {
70+
font-size: 12px;
71+
letter-spacing: 0.1em;
72+
padding: 12px 32px;
73+
border-color: #2a2520;
74+
color: #6b6560;
75+
}
76+
.btn-retake:hover { border-color: #4a4035; color: #c9a87c; }
77+
78+
.progress-bar {
79+
display: flex;
80+
align-items: center;
81+
gap: 20px;
82+
margin-bottom: 48px;
83+
}
84+
.progress-counter {
85+
font-family: 'DM Mono', monospace;
86+
font-size: 12px;
87+
color: #6b6560;
88+
letter-spacing: 0.1em;
89+
white-space: nowrap;
90+
}
91+
.progress-track {
92+
flex: 1;
93+
height: 1px;
94+
background: #2a2520;
95+
position: relative;
96+
}
97+
.progress-fill {
98+
position: absolute;
99+
left: 0; top: 0; height: 1px;
100+
background: #c9a87c;
101+
transition: width 0.4s ease;
102+
}
103+
104+
.choice-btn {
105+
display: block;
106+
width: 100%;
107+
background: transparent;
108+
border: 1px solid #2a2520;
109+
color: #e8e4df;
110+
font-family: 'Newsreader', Georgia, serif;
111+
font-size: 17px;
112+
line-height: 1.65;
113+
font-weight: 300;
114+
padding: 24px 28px;
115+
text-align: left;
116+
cursor: pointer;
117+
transition: all 0.2s ease;
118+
margin-bottom: 16px;
119+
}
120+
.choice-btn:last-child { margin-bottom: 0; }
121+
.choice-btn:hover {
122+
border-color: #4a4035;
123+
background: rgba(201,168,124,0.04);
124+
}
125+
126+
h1.result-type {
127+
font-size: 72px;
128+
font-weight: 300;
129+
text-align: center;
130+
letter-spacing: 0.08em;
131+
margin-bottom: 8px;
132+
color: #c9a87c;
133+
}
134+
.result-title {
135+
text-align: center;
136+
font-size: 20px;
137+
font-style: italic;
138+
color: #9e9590;
139+
margin-bottom: 48px;
140+
font-weight: 300;
141+
}
142+
.result-desc {
143+
font-size: 17px;
144+
line-height: 1.75;
145+
color: #c8c3be;
146+
margin-bottom: 48px;
147+
font-weight: 300;
148+
}
149+
.dim-section {
150+
border-top: 1px solid #2a2520;
151+
padding-top: 36px;
152+
margin-bottom: 48px;
153+
}
154+
.dim-section .label { text-align: left; margin-bottom: 28px; }
155+
.dim-row { margin-bottom: 28px; }
156+
.dim-labels {
157+
display: flex;
158+
justify-content: space-between;
159+
margin-bottom: 8px;
160+
font-family: 'DM Mono', monospace;
161+
font-size: 13px;
162+
letter-spacing: 0.04em;
163+
}
164+
.dim-track {
165+
height: 6px;
166+
background: #2a2520;
167+
border-radius: 3px;
168+
overflow: hidden;
169+
position: relative;
170+
}
171+
.dim-fill {
172+
position: absolute;
173+
left: 0; top: 0; bottom: 0;
174+
background: linear-gradient(90deg, #c9a87c, #a6845a);
175+
border-radius: 3px;
176+
transition: width 1s ease;
177+
}
178+
.center-wrap { text-align: center; }
179+
180+
@media (max-width: 500px) {
181+
h1.intro-title { font-size: 36px; }
182+
h1.result-type { font-size: 56px; }
183+
.choice-btn { font-size: 15px; padding: 20px 22px; }
184+
}
185+
</style>
186+
</head>
187+
<body>
188+
<div id="app" class="fade-in"></div>
189+
190+
<script>
191+
const questions = [
192+
{dim:"EI",a:"A room full of strangers energizes you — each one holds a conversation you haven't had yet.",b:"A room full of strangers drains you — you'd rather go deep with one person than wide with twenty.",aDir:"E",bDir:"I"},
193+
{dim:"EI",a:"You think by talking. The words find their shape as they leave your mouth.",b:"You think by withdrawing. The words must settle internally before they're ready to be spoken.",aDir:"E",bDir:"I"},
194+
{dim:"EI",a:"Silence in a group makes you want to fill it.",b:"Silence in a group feels like a shared understanding.",aDir:"E",bDir:"I"},
195+
{dim:"EI",a:"After a long project, you recharge by going out with people.",b:"After a long project, you recharge by being alone with your thoughts.",aDir:"E",bDir:"I"},
196+
{dim:"EI",a:"You prefer to work through problems out loud with others.",b:"You prefer to work through problems on paper or in your head first.",aDir:"E",bDir:"I"},
197+
{dim:"EI",a:"Your social circle is wide — many acquaintances, open borders.",b:"Your social circle is narrow — few people, but each bond runs deep.",aDir:"E",bDir:"I"},
198+
{dim:"SN",a:"You trust what you can verify — data, experience, what has already happened.",b:"You trust what you can infer — patterns, possibilities, what could happen.",aDir:"S",bDir:"N"},
199+
{dim:"SN",a:"When reading, you focus on what the author said.",b:"When reading, you focus on what the author meant.",aDir:"S",bDir:"N"},
200+
{dim:"SN",a:"You'd rather master existing tools than invent new ones.",b:"You'd rather invent new tools than master existing ones.",aDir:"S",bDir:"N"},
201+
{dim:"SN",a:"Details come first — the big picture assembles itself from the parts.",b:"The big picture comes first — the details fill in once the structure is clear.",aDir:"S",bDir:"N"},
202+
{dim:"SN",a:"You remember events by what happened — facts, sequences, specifics.",b:"You remember events by what they felt like — impressions, connections, significance.",aDir:"S",bDir:"N"},
203+
{dim:"SN",a:"You prefer instructions that are concrete and step-by-step.",b:"You prefer instructions that give you the goal and let you find the path.",aDir:"S",bDir:"N"},
204+
{dim:"TF",a:"A decision is good if it is logically sound, even if someone's feelings get bruised.",b:"A decision is good if it accounts for how people will be affected, even if the logic bends.",aDir:"T",bDir:"F"},
205+
{dim:"TF",a:"When a friend makes a mistake, your instinct is to help them see the error clearly.",b:"When a friend makes a mistake, your instinct is to make sure they feel supported first.",aDir:"T",bDir:"F"},
206+
{dim:"TF",a:"You respect people who are competent and direct, even if they lack warmth.",b:"You respect people who are kind and empathetic, even if they lack precision.",aDir:"T",bDir:"F"},
207+
{dim:"TF",a:"In an argument, you care more about what is true.",b:"In an argument, you care more about what is fair.",aDir:"T",bDir:"F"},
208+
{dim:"TF",a:"Criticism sharpens — you prefer honest feedback over comfortable reassurance.",b:"Encouragement fuels — you perform better when people believe in you.",aDir:"T",bDir:"F"},
209+
{dim:"TF",a:"You find it easier to identify flaws in an argument than to read the mood of a room.",b:"You find it easier to read the mood of a room than to identify flaws in an argument.",aDir:"T",bDir:"F"},
210+
{dim:"JP",a:"An open calendar unsettles you — you'd rather have a plan than possibility.",b:"A packed calendar unsettles you — you'd rather have freedom than structure.",aDir:"J",bDir:"P"},
211+
{dim:"JP",a:"You finish tasks well before the deadline. The weight of incompletion disturbs you.",b:"You finish tasks near the deadline. The pressure of the final hour sharpens you.",aDir:"J",bDir:"P"},
212+
{dim:"JP",a:"Once you make a decision, you commit. Revisiting it feels like regression.",b:"Once you make a decision, you stay open. New information might change everything.",aDir:"J",bDir:"P"},
213+
{dim:"JP",a:"You prefer to settle things — ambiguity is a problem to resolve.",b:"You prefer to keep things open — closure can be premature.",aDir:"J",bDir:"P"},
214+
{dim:"JP",a:"Your workspace tends toward order. Chaos is friction.",b:"Your workspace tends toward organized chaos. Too much order is sterile.",aDir:"J",bDir:"P"},
215+
{dim:"JP",a:"When traveling, you plan the itinerary before arriving.",b:"When traveling, you decide what to do once you're there.",aDir:"J",bDir:"P"},
216+
];
217+
218+
const typeDescriptions = {
219+
INTJ:{title:"The Architect",desc:"You build systems in your head before the world catches up. Strategy is not a skill for you — it is a reflex. You see the long arc of things, and you have little patience for those who cannot. Independence is not a preference; it is a requirement. You trust your internal model of the world more than consensus, and you are usually right to do so."},
220+
INTP:{title:"The Logician",desc:"You live inside frameworks. Every idea is a structure to be stress-tested, every assumption a load-bearing wall that might be hollow. You pursue understanding not for utility but because the gaps in your model bother you the way a misaligned pixel bothers a designer. People sometimes mistake your detachment for coldness. It is not coldness — it is focus."},
221+
ENTJ:{title:"The Commander",desc:"You see inefficiency and your body moves before your mind grants permission. Leadership is not something you aspire to — it is something that happens when you enter a room where no one has a plan. You think in objectives, timelines, and leverage. The world is a system, and systems can be optimized."},
222+
ENTP:{title:"The Debater",desc:"You argue not to win but to discover. Every position is provisional, every certainty an invitation to probe. Your mind moves laterally — while others dig deeper into one hole, you have already opened three more. You thrive in novelty and suffocate in routine. The worst punishment anyone could inflict on you is a solved problem."},
223+
INFJ:{title:"The Advocate",desc:"You perceive patterns in human behavior that others miss entirely. Your intuition operates like sonar — pinging beneath the surface of what people say to detect what they mean. You carry a vision of how things should be, and the distance between that vision and reality is a wound that never fully heals. You give more than you receive, and you know it."},
224+
INFP:{title:"The Mediator",desc:"You inhabit a rich internal world that the external one rarely matches. Your values are not principles you chose — they are structures you discovered inside yourself, non-negotiable and load-bearing. You feel the weight of inauthenticity like a physical sensation. You would rather fail on your own terms than succeed on borrowed ones."},
225+
ENFJ:{title:"The Protagonist",desc:"You read people the way engineers read schematics — the structure is visible to you, the stress points obvious. You organize human energy the way others organize data. Your gift is making people feel seen; your burden is that you rarely feel seen yourself. You lead through conviction, and conviction through empathy."},
226+
ENFP:{title:"The Campaigner",desc:"You see potential everywhere — in people, in ideas, in half-formed plans that others dismiss. Your enthusiasm is not performance; it is the natural output of a mind that genuinely believes things can be better. You connect dots across domains that others keep separate. Your challenge is not starting — it is finishing."},
227+
ISTJ:{title:"The Logistician",desc:"You are the bedrock others build on without noticing. Duty is not a burden for you — it is the structure that gives life its shape. You trust what has been tested, respect what has endured, and distrust what promises revolution. Your memory for detail is formidable, and your standards do not bend."},
228+
ISFJ:{title:"The Defender",desc:"You remember what others forget — the small commitments, the unspoken needs, the quiet promises that hold relationships together. Your care operates in the background, invisible until it stops. You do not seek recognition for your contributions, which is precisely why you deserve it."},
229+
ESTJ:{title:"The Executive",desc:"You see disorder and impose structure. Not because you enjoy control, but because someone must, and you are the one who will. Rules exist for reasons. Institutions function because people like you maintain them. Your directness can sting, but no one doubts where you stand."},
230+
ESFJ:{title:"The Consul",desc:"You hold groups together through attention — to needs, to traditions, to the invisible threads of social cohesion that most people take for granted. Harmony is not a luxury for you; it is infrastructure. When it breaks, you feel it in your body before your mind names it."},
231+
ISTP:{title:"The Virtuoso",desc:"You understand systems by taking them apart. Theory bores you unless it touches something you can build, fix, or break. Your hands think faster than your words, and your calm under pressure is not an act — it is the natural state of someone who trusts their own competence. You move through crises the way water moves through rock."},
232+
ISFP:{title:"The Adventurer",desc:"You live closer to the present than most. Sensation, texture, beauty — these are not decorations on top of life but the substance of it. Your values run deep but you rarely preach them. You express what matters through action, through creation, through the quiet choices that accumulate into a life that looks like you."},
233+
ESTP:{title:"The Entrepreneur",desc:"You read rooms and situations the way traders read markets — fast, instinctive, already positioning for the next move before others have finished analyzing the last one. You learn by doing, not by studying. Risk does not frighten you; stagnation does."},
234+
ESFP:{title:"The Entertainer",desc:"You make the present tense feel like the only tense that matters. Your energy is not performance — it is overflow. You notice what people need in the moment and you deliver it without hesitation. The world is a stage not because you act, but because you are fully alive on it."},
235+
};
236+
237+
let current = 0;
238+
let answers = {};
239+
let phase = "intro";
240+
const app = document.getElementById("app");
241+
242+
function transition(fn) {
243+
app.classList.remove("fade-in");
244+
app.classList.add("fade-out");
245+
setTimeout(() => { fn(); app.classList.remove("fade-out"); app.classList.add("fade-in"); }, 300);
246+
}
247+
248+
function renderIntro() {
249+
app.innerHTML = `
250+
<div style="text-align:center">
251+
<div class="label">Personality Instrument</div>
252+
<h1 class="intro-title">Myers–Briggs<br>Type Indicator</h1>
253+
<p class="intro-desc">Twenty-four forced choices. Each pair presents two modes of operating in the world. Neither is superior. Pick the one that describes your default — not who you wish to be, but who you are when no one is watching.</p>
254+
<button class="btn-begin" id="beginBtn">Begin</button>
255+
</div>`;
256+
document.getElementById("beginBtn").addEventListener("click", () => {
257+
transition(() => { phase = "test"; renderQuestion(); });
258+
});
259+
}
260+
261+
function renderQuestion() {
262+
const q = questions[current];
263+
const progress = (current / questions.length) * 100;
264+
app.innerHTML = `
265+
<div class="progress-bar">
266+
<span class="progress-counter">${String(current+1).padStart(2,"0")} / ${questions.length}</span>
267+
<div class="progress-track"><div class="progress-fill" style="width:${progress}%"></div></div>
268+
</div>
269+
<div>
270+
<button class="choice-btn" id="choiceA">${q.a}</button>
271+
<button class="choice-btn" id="choiceB">${q.b}</button>
272+
</div>`;
273+
document.getElementById("choiceA").addEventListener("click", () => handleAnswer("a"));
274+
document.getElementById("choiceB").addEventListener("click", () => handleAnswer("b"));
275+
}
276+
277+
function handleAnswer(choice) {
278+
const q = questions[current];
279+
answers[current] = choice === "a" ? q.aDir : q.bDir;
280+
if (current < questions.length - 1) {
281+
transition(() => { current++; renderQuestion(); });
282+
} else {
283+
const tally = {E:0,I:0,S:0,N:0,T:0,F:0,J:0,P:0};
284+
Object.values(answers).forEach(d => tally[d]++);
285+
const type = (tally.E>=tally.I?"E":"I")+(tally.S>=tally.N?"S":"N")+(tally.T>=tally.F?"T":"F")+(tally.J>=tally.P?"J":"P");
286+
transition(() => { phase = "result"; renderResult(type, tally); });
287+
}
288+
}
289+
290+
function dimBar(left, right, leftScore, rightScore) {
291+
const total = leftScore + rightScore;
292+
const pct = total > 0 ? Math.round((leftScore/total)*100) : 50;
293+
return `
294+
<div class="dim-row">
295+
<div class="dim-labels">
296+
<span style="color:${pct>=50?"#e8e4df":"#6b6560"}">${left} ${pct}%</span>
297+
<span style="color:${pct<50?"#e8e4df":"#6b6560"}">${right} ${100-pct}%</span>
298+
</div>
299+
<div class="dim-track"><div class="dim-fill" style="width:${pct}%"></div></div>
300+
</div>`;
301+
}
302+
303+
function renderResult(type, scores) {
304+
const info = typeDescriptions[type];
305+
app.innerHTML = `
306+
<div class="label" style="margin-bottom:16px">Your Type</div>
307+
<h1 class="result-type">${type}</h1>
308+
<div class="result-title">${info.title}</div>
309+
<p class="result-desc">${info.desc}</p>
310+
<div class="dim-section">
311+
<div class="label" style="text-align:left;margin-bottom:28px">Dimension Breakdown</div>
312+
${dimBar("E","I",scores.E,scores.I)}
313+
${dimBar("S","N",scores.S,scores.N)}
314+
${dimBar("T","F",scores.T,scores.F)}
315+
${dimBar("J","P",scores.J,scores.P)}
316+
</div>
317+
<div class="center-wrap"><button class="btn-retake" id="retakeBtn">Retake</button></div>`;
318+
document.getElementById("retakeBtn").addEventListener("click", () => {
319+
transition(() => { current=0; answers={}; phase="intro"; renderIntro(); });
320+
});
321+
}
322+
323+
renderIntro();
324+
</script>
325+
</body>
326+
</html>

0 commit comments

Comments
 (0)