<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>How Well Do You Actually Know Me? 💗</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Playfair+Display:wght@600;700&display=swap');
:root {
--pink: #e88aa8;
--lavender: #c9b9e8;
--cream: #fffaf7;
--text: #332d39;
--muted: #77707b;
--green: #4f9b78;
--red: #c96578;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
font-family: "DM Sans", sans-serif;
color: var(--text);
background:
radial-gradient(circle at 10% 10%,
rgba(232,138,168,.28),
transparent 30%),
radial-gradient(circle at 90% 85%,
rgba(201,185,232,.34),
transparent 32%),
linear-gradient(
145deg,
#fff8f8,
#f7f1fb 55%,
#fffaf5
);
}
#app {
width: min(680px, 100%);
min-height: 100vh;
margin: auto;
padding: 22px 16px 30px;
display: flex;
align-items: center;
}
.screen {
width: 100%;
animation: appear .45s ease;
}
.hidden {
display: none !important;
}
@keyframes appear {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* START SCREEN */
.hero {
text-align: center;
padding: 30px 8px;
}
.heart {
font-size: 46px;
display: block;
margin-bottom: 15px;
animation: pulse 2.4s infinite;
}
@keyframes pulse {
50% {
transform: scale(1.07);
}
}
.logo {
font-size: 13px;
font-weight: 700;
letter-spacing: .12em;
text-transform: uppercase;
color: #a06a82;
margin-bottom: 20px;
}
h1,
h2 {
font-family: "Playfair Display", serif;
}
h1 {
font-size: clamp(34px, 9vw, 56px);
line-height: 1.05;
letter-spacing: -.035em;
margin: 0;
}
.subtitle {
font-size: 16px;
line-height: 1.65;
color: var(--muted);
margin: 18px auto 30px;
}
.card {
background: rgba(255,255,255,.88);
border: 1px solid rgba(255,255,255,.9);
box-shadow:
0 18px 50px rgba(89,66,91,.11);
backdrop-filter: blur(12px);
border-radius: 28px;
padding: 25px;
}
/* BUTTON */
.btn {
width: 100%;
border: 0;
border-radius: 17px;
padding: 16px 18px;
font:
700 15px "DM Sans";
cursor: pointer;
transition:
.2s transform,
.2s box-shadow;
}
.btn:active {
transform: scale(.98);
}
.primary {
color: white;
background:
linear-gradient(
135deg,
#e48aa7,
#c79ddd
);
box-shadow:
0 12px 25px rgba(208,137,171,.28);
}
.primary:hover {
transform: translateY(-1px);
box-shadow:
0 15px 30px rgba(208,137,171,.38);
}
/* QUIZ */
.topline {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
font-size: 13px;
font-weight: 700;
color: var(--muted);
}
.progress {
height: 8px;
background: #eee8ef;
border-radius: 99px;
overflow: hidden;
margin-bottom: 25px;
}
.progress span {
display: block;
height: 100%;
width: 0;
background:
linear-gradient(
90deg,
#e58ba8,
#b99adf
);
border-radius: inherit;
transition:
width .35s ease;
}
.question {
font-family: "Playfair Display", serif;
font-size:
clamp(24px, 6vw, 32px);
line-height: 1.2;
margin-bottom: 22px;
}
.options {
display: grid;
gap: 11px;
}
.option {
width: 100%;
text-align: left;
background: white;
border:
1.5px solid #eee7ee;
border-radius: 16px;
padding: 15px;
font:
500 15px/1.42 "DM Sans";
color: var(--text);
cursor: pointer;
transition:
.18s ease;
min-height: 54px;
display: flex;
align-items: center;
gap: 12px;
}
.option:hover {
border-color: #d8b5c7;
transform: translateY(-1px);
box-shadow:
0 7px 16px rgba(80,60,80,.07);
}
.option:disabled {
cursor: default;
transform: none;
}
.letter {
flex:
0 0 30px;
height: 30px;
border-radius: 10px;
background: #f7edf3;
display: grid;
place-items: center;
font-size: 12px;
font-weight: 700;
color: #98657b;
}
.option.correct {
border-color: var(--green);
background: #edf8f2;
}
.option.correct .letter {
background: #d7eee3;
color: #39775b;
}
.option.wrong {
border-color: var(--red);
background: #fff0f3;
}
.option.wrong .letter {
background: #f8dbe2;
color: #a24f61;
}
/* FEEDBACK */
.feedback {
margin-top: 16px;
padding: 13px 15px;
border-radius: 14px;
font-size: 14px;
font-weight: 700;
animation: appear .25s ease;
}
.feedback.good {
background: #edf8f2;
color: #39775b;
}
.feedback.bad {
background: #fff0f3;
color: #a24f61;
}
.next {
margin-top: 12px;
}
/* RESULT */
.result {
text-align: center;
padding: 28px 20px;
}
.trophy {
font-size: 52px;
}
.badge {
display: inline-block;
padding: 7px 11px;
border-radius: 99px;
background: #f7e9f0;
color: #95647c;
font-size: 12px;
font-weight: 700;
margin: 12px 0;
}
.result h2 {
font-size: clamp(27px, 7vw, 40px);
margin: 5px 0;
}
.score {
font-family: "Playfair Display", serif;
font-size: 64px;
line-height: 1;
color: #9b6682;
margin: 15px 0 4px;
}
.percent {
color: var(--muted);
font-weight: 700;
margin-bottom: 20px;
}
.result p {
line-height: 1.6;
color: var(--muted);
max-width: 480px;
margin:
10px auto 25px;
}
.footer {
font-size: 12px;
color: #9a939d;
text-align: center;
margin-top: 18px;
}
@media(max-width:430px) {
#app {
padding:
15px 12px 24px;
}
.card {
padding: 20px;
border-radius: 24px;
}
.hero {
padding: 18px 5px;
}
.option {
padding: 14px 12px;
}
}
</style>
</head>
<body>
<div id="app">
<!-- START -->
<section id="start" class="screen">
<div class="hero">
<span class="heart">💗</span>
<div class="logo">
Friendship Test
</div>
<h1>
HOW WELL DO YOU<br>
ACTUALLY KNOW ME?
</h1>
<p class="subtitle">
30 questions.<br>
No cheating.<br>
Let's see if you actually know me...
</p>
<button
class="btn primary"
id="startBtn">
START THE QUIZ →
</button>
</div>
</section>
<!-- QUIZ -->
<section id="quiz" class="screen hidden">
<div class="card">
<div class="topline">
<span id="counter">
Question 1 / 30
</span>
<span id="scoreTop">
Score: 0
</span>
</div>
<div class="progress">
<span id="progress"></span>
</div>
<div
id="question"
class="question">
</div>
<div
id="options"
class="options">
</div>
<div
id="feedback"
class="hidden">
</div>
<button
id="nextBtn"
class="btn primary next hidden">
NEXT →
</button>
</div>
</section>
<!-- RESULT -->
<section id="result" class="screen hidden">
<div class="card result">
<div
class="trophy"
id="trophy">
🏆
</div>
<div class="badge">
QUIZ COMPLETE
</div>
<h2 id="resultTitle"></h2>
<div
class="score"
id="finalScore">
</div>
<div
class="percent"
id="percentage">
</div>
<p id="resultMessage"></p>
<button
class="btn primary"
id="againBtn">
PLAY AGAIN ↻
</button>
<div class="footer">
Made for my friends 💗
</div>
</div>
</section>
</div>
<script>
const questions = [
[
"What's my MBTI?",
[
"INFP",
"ISFP",
"ISFJ",
"ENFP"
],
1
],
[
"What's my zodiac sign?",
[
"Pisces",
"Capricorn",
"Aquarius",
"Gemini"
],
2
],
[
"Which description is closest to how I see myself?",
[
"Someone who usually plans everything before doing it",
"Someone who tends to follow what feels right to me",
"Someone who prefers having other people make decisions",
"Someone who enjoys being the centre of attention"
],
1
],
[
"If I become interested in something, which is more likely?",
[
"I enjoy it casually and move on",
"I start looking into more things related to it",
"I wait until someone else tells me about it",
"I usually lose interest after a few days"
],
1
],
[
"Which matters more to me when I enjoy something?",
[
"Whether everyone else likes it",
"Whether it's currently popular",
"Whether I personally connect with it",
"Whether it's considered objectively good"
],
2
],
[
"What was my first BL drama?",
[
"Bad Buddy",
"The Eclipse",
"My School President",
"Khemjira"
],
3
],
[
"What originally made me curious about Khemjira?",
[
"I saw people talking about the storyline",
"I was curious about one of the actors after seeing a reel",
"Someone recommended it to me directly",
"I was looking for a new Thai drama"
],
1
],
[
"When I'm deciding whether I like a BL couple, which matters most to me?",
[
"Their individual visuals",
"Their popularity",
"Their chemistry together",
"How many cute scenes they have"
],
2
],
[
"Which kind of BL romance usually catches my attention more?",
[
"Very soft romance with almost no tension",
"Slow romance where the characters barely interact",
"Strong chemistry with tension and emotional development",
"Comedy where romance isn't the main focus"
],
2
],
[
"If I'm watching a drama and one character keeps hurting the person they supposedly love, what am I most likely to think?",
[
"It's probably necessary for the plot.",
"I'll wait and see how it develops.",
"I can tolerate it if the ending is good.",
"Why am I suffering through this?"
],
3
],
[
"What would make me more likely to drop a BL?",
[
"The story has some angst",
"The episodes are short",
"The pacing becomes frustrating and I'm no longer enjoying the relationship",
"There are too many romantic scenes"
],
2
],
[
"If a BL couple has amazing chemistry but the story takes too long to develop, what could happen?",
[
"I'll definitely finish it because of the chemistry",
"I'll probably lose interest eventually",
"I'll immediately hate the couple",
"I'll stop watching BL altogether"
],
1
],
[
"Which ending would I most likely want after investing in a couple?",
[
"Open ending",
"Bittersweet ending",
"Happy ending",
"Ambiguous ending"
],
2
],
[
"If several BL episodes release around the same time, what's my biggest problem?",
[
"I don't like watching two episodes together",
"I have to decide which one to watch first",
"I don't remember what happened previously",
"I usually don't notice release times"
],
1
],
[
"Which situation sounds most frustrating for me while watching a BL?",
[
"A character is too shy to confess",
"The couple has a misunderstanding",
"A character keeps prioritising everyone else while neglecting the person they love",
"The couple doesn't have enough cute moments"
],
2
],
[
"How would I describe my music taste?",
[
"I mainly stick to one genre",
"I mostly listen to whatever is popular",
"I listen to whatever I can relate to and feel good listening to",
"I mainly listen to songs from dramas"
],
2
],
[
"Which of these songs is actually in my music?",
[
"Love Back",
"Love Story",
"Love Me Like You Do",
"Love Yourself"
],
0
],
[
"Which artist appears in my downloaded songs?",
[
"Why Don't We",
"The Vamps",
"OneRepublic",
"5 Seconds of Summer"
],
0
],
[
"Which pair of artists appears together in one of my songs?",
[
"Niall Horan & Shawn Mendes",
"Anne-Marie & Niall Horan",
"Troye Sivan & Lauv",
"Taylor Swift & Shawn Mendes"
],
1
],
[
"Which MONSTA X song do I have?",
[
"Love Killa",
"Someone's Someone",
"Shoot Out",
"Middle of the Night"
],
1
],
[
"Which 5 Seconds of Summer song is in my music?",
[
"Teeth",
"Youngblood",
"Lie to Me",
"Easier"
],
1
],
[
"Which Taylor Swift song did I show you?",
[
"Cruel Summer",
"Red (Taylor's Version)",
"Delicate",
"Anti-Hero"
],
1
],
[
"Which NIKI song is in my music?",
[
"Every Summertime",
"Lowkey",
"Take A Chance With Me",
"La La Lost You"
],
2
],
[
"Which song by The Chainsmokers is in my downloads?",
[
"Closer",
"Paris",
"Takeaway",
"Don't Let Me Down"
],
2
],
[
"Which of these is also in my music?",
[
"Our Song by Anne-Marie & Niall Horan",
"Perfect by Ed Sheeran",
"Adore You by Harry Styles",
"Dusk Till Dawn by ZAYN"
],
0
],
[
"If I say a song is good, what's more likely to be the reason?",
[
"It's technically difficult to sing",
"It's trending everywhere",
"I connect with the feeling of the song",
"Someone I like recommended it"
],
2
],
[
"If I find a new drama I'm interested in while already watching several others, what's the most realistic problem?",
[
"I'll immediately drop everything else",
"I'll add it to my list and somehow make my schedule even worse",
"I'll refuse to watch it until it finishes",
"I'll forget about it completely"
],
1
],
[
"What is more likely to make me continue watching a BL even when the plot isn't perfect?",
[
"The episode length",
"The actors' popularity",
"The couple's chemistry",
"The number of episodes remaining"
],
2
],
[
"Which combination feels most like my taste?",
[
"One favourite genre + one favourite artist + one favourite drama",
"Lots of different songs + BL dramas + things I personally connect with",
"Mostly whatever is trending + occasional dramas",
"One type of entertainment that I stick with"
],
1
],
[
"FINAL BOSS: Which one describes me most accurately?",
[
"Aquarius + ISFP + BL lover + music depends on my mood/connection + gets invested when something really clicks",
"Aquarius + INFP + mostly K-drama + listens mainly to one genre + rarely gets attached to fictional characters",
"Pisces + ISFP + watches BL occasionally + mainly listens to trending music + prefers predictable stories",
"Capricorn + ISFJ + mostly romance dramas + listens mainly to one artist + doesn't get emotionally invested in shows"
],
0
]
];
const goodReactions = [
"Okayyy... you actually know me 👀",
"Correct! I'm impressed.",
"You remembered that?!",
"Okay, you pay attention.",
"That's actually scary 😭"
];
const badReactions = [
"Nope 😭",
"How did you choose that?",
"You were supposed to know this!",
"We're having a conversation after this 💀",
"Interesting choice... very interesting."
];
const results = [
[
7,
"DO WE EVEN KNOW EACH OTHER? 😭",
"I'm starting to question whether you've actually been paying attention.",
"😭"
],
[
14,
"YOU KNOW THE BASICS 👀",
"You've definitely been around me, but some of my lore clearly escaped you.",
"👀"
],
[
20,
"OKAY, YOU KNOW ME",
"Not bad. You actually remembered quite a few things.",
"💗"
],
[
25,
"YOU REALLY KNOW ME 💗",
"Okay, you pay attention. I'm impressed.",
"💞"
],
[
29,
"THIS IS GETTING SCARY 👀",
"How do you know all of this? Have you been taking notes?",
"👀"
],
[
30,
"YOU KNOW ME TOO WELL 🏆",
"Excuse me??? You got everything right. At this point you know my lore better than you should.",
"🏆"
]
];
let current = 0;
let score = 0;
let locked = false;
let quizQuestions = [];
const $ = id => document.getElementById(id);
function shuffle(array) {
const arr = [...array];
for (
let i = arr.length - 1;
i > 0;
i--
) {
const j =
Math.floor(
Math.random() * (i + 1)
);
[
arr[i],
arr[j]
] =
[
arr[j],
arr[i]
];
}
return arr;
}
function buildQuiz() {
quizQuestions =
questions.map(
([question, options, correct]) => {
const items =
options.map(
(text, index) => ({
text,
correct:
index === correct
})
);
return {
question,
items: shuffle(items)
};
}
);
}
function showScreen(screen) {
["start", "quiz", "result"]
.forEach(id => {
$(id)
.classList
.toggle(
"hidden",
id !== screen
);
});
}
function renderQuestion() {
locked = false;
const item =
quizQuestions[current];
$("counter").textContent =
`Question ${current + 1} / ${questions.length}`;
$("scoreTop").textContent =
`Score: ${score}`;
$("progress").style.width =
`${(current / questions.length) * 100}%`;
$("question").textContent =
item.question;
$("feedback").className =
"hidden";
$("feedback").textContent = "";
$("nextBtn")
.classList
.add("hidden");
const options =
$("options");
options.innerHTML = "";
item.items.forEach(
(item, index) => {
const button =
document.createElement("button");
button.className =
"option";
button.innerHTML = `
<span class="letter">
${String.fromCharCode(65 + index)}
</span>
<span>
${item.text}
</span>
`;
button.addEventListener(
"click",
() => chooseAnswer(index)
);
options.appendChild(button);
}
);
}
function chooseAnswer(index) {
if (locked) return;
locked = true;
const item =
quizQuestions[current];
const buttons =
[...$("options").children];
const chosen =
item.items[index];
buttons.forEach(
(button, i) => {
button.disabled = true;
if (item.items[i].correct) {
button.classList.add("correct");
}
if (
i === index &&
!chosen.correct
) {
button.classList.add("wrong");
}
}
);
if (chosen.correct) {
score++;
$("feedback").textContent =
goodReactions[
Math.floor(
Math.random() *
goodReactions.length
)
];
$("feedback").className =
"feedback good";
} else {
$("feedback").textContent =
badReactions[
Math.floor(
Math.random() *
badReactions.length
)
];
$("feedback").className =
"feedback bad";
}
$("scoreTop").textContent =
`Score: ${score}`;
$("progress").style.width =
`${((current + 1) / questions.length) * 100}%`;
$("nextBtn").textContent =
current === questions.length - 1
? "SEE MY RESULT →"
: "NEXT →";
$("nextBtn")
.classList
.remove("hidden");
}
function nextQuestion() {
current++;
if (
current >=
questions.length
) {
showResult();
return;
}
renderQuestion();
window.scrollTo({
top: