<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MBA Application Timeline — R1</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500&family=DM+Serif+Display:ital@0;1&display=swap" rel="stylesheet">
<style>
:root {
--bg: #FFFFFF;
--surface: #FFFFFF;
--border: rgba(0,0,0,0.09);
--border-mid: rgba(0,0,0,0.14);
--text-primary: #1a1a18;
--text-secondary: #5a5a55;
--text-tertiary: #9a9a92;
--cat-appreq-fill: #D6EDBE; --cat-appreq-text: #2a5a0a; --cat-appreq-badge: #EAF3DE;
--cat-research-fill: #BDD8F5; --cat-research-text: #0a3f7a; --cat-research-badge: #E6F1FB;
--cat-profile-fill: #A8E6D0; --cat-profile-text: #074a32; --cat-profile-badge: #E1F5EE;
--cat-strategy-fill: #FAD99A; --cat-strategy-text: #5a2e00; --cat-strategy-badge: #FAEEDA;
--cat-appmtrl-fill: #D4CFFA; --cat-appmtrl-text: #2e236e; --cat-appmtrl-badge: #EEEDFE;
--cat-interview-fill:#FADADD; --cat-interview-text:#7a0a1a; --cat-interview-badge:#FCEEF0;
--phase-foundation-bg: #EAF3DE; --phase-foundation-text: #27500A;
--phase-strategy-bg: #E6F1FB; --phase-strategy-text: #0C447C;
--phase-execution-bg: #FAEEDA; --phase-execution-text: #633806;
--phase-finish-bg: #EEEDFE; --phase-finish-text: #3C3489;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'DM Sans', sans-serif;
background: var(--bg);
color: var(--text-primary);
min-height: 100vh;
padding: 2.5rem 2rem 4rem;
}
.page-header { margin-bottom: 2rem; }
.eyebrow {
font-size: 11px;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--text-tertiary);
margin-bottom: 8px;
}
h1 {
font-family: 'DM Serif Display', serif;
font-size: clamp(24px, 4vw, 36px);
font-weight: 400;
line-height: 1.15;
color: var(--text-primary);
margin-bottom: 10px;
}
h1 em { font-style: italic; color: var(--text-secondary); }
.intro-text {
font-size: 13.5px;
color: var(--text-secondary);
line-height: 1.7;
max-width: 640px;
margin-bottom: 0.6rem;
}
.subtitle {
font-size: 13.5px;
color: var(--text-secondary);
line-height: 1.6;
max-width: 600px;
margin-bottom: 1.75rem;
}
.phase-descriptions {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 10px;
margin-bottom: 1.75rem;
}
.phase-card {
border-radius: 10px;
padding: 12px 14px;
border: 0.5px solid var(--border);
}
.phase-card-label {
font-size: 10px;
font-weight: 500;
letter-spacing: 0.06em;
text-transform: uppercase;
margin-bottom: 4px;
}
.phase-card-months { font-size: 11px; margin-bottom: 6px; opacity: 0.7; }
.phase-card-desc { font-size: 12px; line-height: 1.55; }
.phase-card.foundation { background: var(--phase-foundation-bg); color: var(--phase-foundation-text); }
.phase-card.strategy { background: var(--phase-strategy-bg); color: var(--phase-strategy-text); }
.phase-card.execution { background: var(--phase-execution-bg); color: var(--phase-execution-text); }
.phase-card.finish { background: var(--phase-finish-bg); color: var(--phase-finish-text); }
.note { font-size: 11.5px; color: var(--text-tertiary); font-style: italic; margin-bottom: 1rem; }
.hint { font-size: 11.5px; color: var(--text-tertiary); margin-bottom: 10px; }
.controls {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
margin-bottom: 1rem;
}
.controls-label { font-size: 11px; color: var(--text-tertiary); margin-right: 2px; }
.f-btn {
font-family: 'DM Sans', sans-serif;
font-size: 11px;
font-weight: 400;
padding: 5px 11px;
border-radius: 20px;
border: 1px solid var(--border-mid);
background: transparent;
color: var(--text-secondary);
cursor: pointer;
transition: all 0.15s;
}
.f-btn:hover { opacity: 0.85; }
.gantt-wrap {
background: var(--surface);
border: 0.5px solid var(--border);
border-radius: 12px;
overflow: hidden;
}
.phase-strip { display: grid; grid-template-columns: 180px repeat(12, 1fr); }
.phase-strip-cell {
font-size: 10px;
font-weight: 500;
text-align: center;
padding: 6px 4px;
letter-spacing: 0.03em;
}
.phase-strip-cell.foundation { background: var(--phase-foundation-bg); color: var(--phase-foundation-text); }
.phase-strip-cell.strategy { background: var(--phase-strategy-bg); color: var(--phase-strategy-text); }
.phase-strip-cell.execution { background: var(--phase-execution-bg); color: var(--phase-execution-text); }
.phase-strip-cell.finish { background: var(--phase-finish-bg); color: var(--phase-finish-text); }
.grid-header {
display: grid;
grid-template-columns: 180px repeat(12, 1fr);
border-top: 0.5px solid var(--border);
border-bottom: 0.5px solid var(--border);
background: var(--bg);
}
.grid-header div {
font-size: 10px;
font-weight: 500;
color: var(--text-tertiary);
text-align: center;
padding: 5px 2px;
border-left: 0.5px solid var(--border);
}
.grid-header div:first-child { border-left: none; text-align: left; padding-left: 14px; }
.row-wrapper { border-top: 0.5px solid var(--border); }
.row-wrapper:first-child { border-top: none; }
/* Row fading — controlled by JS adding/removing .faded class on row-wrapper */
.row-wrapper.faded { opacity: 0.18; }
.row-wrapper.faded .act-label { color: var(--text-tertiary); }
.activity-row {
display: grid;
grid-template-columns: 180px repeat(12, 1fr);
cursor: pointer;
transition: background 0.12s;
min-height: 36px;
}
.activity-row:hover { background: #fafaf8; }
.activity-row.active { background: #fafaf8; }
.act-label {
font-size: 12px;
color: var(--text-primary);
padding: 7px 10px 7px 14px;
display: flex;
align-items: center;
line-height: 1.3;
gap: 6px;
}
.act-label .expand-icon {
flex-shrink: 0;
width: 14px;
height: 14px;
border-radius: 50%;
border: 0.5px solid var(--border-mid);
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
color: var(--text-tertiary);
transition: transform 0.2s;
margin-left: auto;
}
.activity-row.active .expand-icon { transform: rotate(45deg); }
.act-cell {
border-left: 0.5px solid var(--border);
padding: 7px 3px;
display: flex;
align-items: center;
}
.bar { width: 100%; height: 18px; border-radius: 3px; }
.bar.dim { opacity: 0.3; }
.bar.appreq { background: var(--cat-appreq-fill); }
.bar.research { background: var(--cat-research-fill); }
.bar.profile { background: var(--cat-profile-fill); }
.bar.strategy { background: var(--cat-strategy-fill); }
.bar.appmtrl { background: var(--cat-appmtrl-fill); }
.bar.interview{ background: var(--cat-interview-fill); }
.milestone-dot {
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--cat-interview-text);
margin: 0 auto;
}
.detail-panel { overflow: hidden; max-height: 0; transition: max-height 0.28s ease; }
.detail-panel.open { max-height: 320px; }
.detail-inner {
padding: 12px 14px 14px 194px;
background: #fafaf8;
border-top: 0.5px solid var(--border);
}
.tip-tag {
display: inline-block;
font-size: 10px;
font-weight: 500;
padding: 3px 9px;
border-radius: 4px;
margin-bottom: 7px;
letter-spacing: 0.02em;
}
.detail-text {
font-size: 12.5px;
color: var(--text-secondary);
line-height: 1.65;
max-width: 600px;
}
.legend {
display: flex;
gap: 14px;
flex-wrap: wrap;
padding: 12px 14px;
border-top: 0.5px solid var(--border);
background: var(--bg);
}
.leg { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-tertiary); }
.leg-dot { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
media (max-width: 700px) {
body { padding: 1.25rem 1rem 3rem; }
.phase-descriptions { grid-template-columns: 1fr 1fr; }
.gantt-wrap { overflow-x: auto; }
.phase-strip, .grid-header, .activity-row {
grid-template-columns: 130px repeat(12, minmax(26px, 1fr));
min-width: 500px;
}
.detail-inner { padding-left: 14px; }
}
</style>
</head>
<body>
<div class="page-header">
<p class="eyebrow">MBA applications — Round 1</p>
<h1>Your MBA Application Year, <em>Mapped Out</em></h1>
<p class="intro-text">Applying to business school can feel chaotic because many moving parts overlap at the same time. You have to take tests, conduct b-school research, write essays, talk to recommenders, fill application forms and prepare for interviews. The process becomes much more manageable when you design a structure and use it to guide you throughout the application cycle.</p>
<p class="subtitle">Here's a month-by-month guide to navigating the b-school application process — from the first prep to the final decision. Click any row for guidance.</p>
</div>
<div class="phase-descriptions">
<div class="phase-card foundation">
<div class="phase-card-label">Foundation</div>
<div class="phase-card-months">Jan – Jun</div>
<div class="phase-card-desc">Build the base before any application work begins. Take your tests, attend events and research b-schools, build your profile. Nothing is application-specific here, but these are the building blocks for submitting your best applications.</div>
</div>
<div class="phase-card strategy">
<div class="phase-card-label">Strategy</div>
<div class="phase-card-months">Apr – Jul</div>
<div class="phase-card-desc">Make a plan geared towards R1 deadlines. Finalize your school list, choose your R1/R2 split, lock recommenders, and get your transcripts in order. Brainstorm on essay stories.</div>
</div>
<div class="phase-card execution">
<div class="phase-card-label">Execution</div>
<div class="phase-card-months">Jul – Oct</div>
<div class="phase-card-desc">Create your resume in MBA format, write essays, remind recommenders to submit references. Complete your application forms and video interviews.</div>
</div>
<div class="phase-card finish">
<div class="phase-card-label">Finish line</div>
<div class="phase-card-months">Oct – Dec</div>
<div class="phase-card-desc">After submitting the applications, the focus shifts to preparing for interviews, waiting for results and preparing your Round 2 strategy. If you need any profile enhancements for R2, start this now.</div>
</div>
</div>
<p class="note">Note: R1 deadlines fall between September and October.</p>
<p class="hint"><strong>Click a category to highlight only those rows. Click "Show all" to reset.</strong></p>
<div class="controls" id="filters"></div>
<div class="gantt-wrap">
<div class="phase-strip">
<div class="phase-strip-cell"></div>
<div class="phase-strip-cell foundation" style="grid-column:span 6">Foundation</div>
<div class="phase-strip-cell strategy" style="grid-column:span 2">Strategy</div>
<div class="phase-strip-cell execution" style="grid-column:span 2">Execution</div>
<div class="phase-strip-cell finish" style="grid-column:span 2">Finish line</div>
</div>
<div class="grid-header">
<div>Activity</div>
<div>Jan</div><div>Feb</div><div>Mar</div>
<div>Apr</div><div>May</div><div>Jun</div>
<div>Jul</div><div>Aug</div><div>Sep</div>
<div>Oct</div><div>Nov</div><div>Dec</div>
</div>
<div id="rows"></div>
<div class="legend" id="legend"></div>
</div>
<script>
// ── Category definitions (no special chars in keys) ──────────────────────────
const CATEGORIES = [
{ key: "appreq", label: "Application Requirement", fill: "var(--cat-appreq-fill)", badge: "var(--cat-appreq-badge)", text: "var(--cat-appreq-text)" },
{ key: "research", label: "Research", fill: "var(--cat-research-fill)", badge: "var(--cat-research-badge)", text: "var(--cat-research-text)" },
{ key: "profile", label: "Profile Building", fill: "var(--cat-profile-fill)", badge: "var(--cat-profile-badge)", text: "var(--cat-profile-text)" },
{ key: "strategy", label: "Strategy", fill: "var(--cat-strategy-fill)", badge: "var(--cat-strategy-badge)", text: "var(--cat-strategy-text)" },
{ key: "appmtrl", label: "Application Material", fill: "var(--cat-appmtrl-fill)", badge: "var(--cat-appmtrl-badge)", text: "var(--cat-appmtrl-text)" },
{ key: "interview",label: "Interview", fill: "var(--cat-interview-fill)",badge: "var(--cat-interview-badge)",text: "var(--cat-interview-text)" },
];
const catMap = {};
CATEGORIES.forEach(c => catMap[c.key] = c);
// ── Activities (cat = key from CATEGORIES) ───────────────────────────────────
const activities = [
{
label: "GMAT / GRE prep", cat: "appreq",
bars: [1,1,1,1,1,1,1,0,0,0,0,0],
dim: [0,0,0,0,0,1,1,0,0,0,0,0],
tip: "Plan to take by May or June",
detail: "Plan to take your GMAT/GRE by May or June. If you don't reach your target score, keep a buffer to retake the test by the end of July so that your applications are not delayed."
},
{
label: "B-school research", cat: "research",
bars: [1,1,1,1,1,1,1,1,1,1,1,1],
dim: [1,1,1,0,0,0,0,0,0,0,1,1],
tip: "Ongoing throughout the year",
detail: "Start your b-school research as early as possible. This should be an ongoing effort that continues throughout the year, as your understanding of the schools will keep evolving. Your research should inform your school selection, essay content and interview prep."
},
{
label: "Events & info sessions", cat: "research",
bars: [1,1,1,1,1,1,1,1,1,1,0,0],
dim: [1,1,1,0,0,0,0,0,0,0,0,0],
tip: "Attend for insights + fee waivers",
detail: "Attend events and info sessions hosted by b-schools and student clubs. They are useful for understanding academic offerings, culture, career opportunities and for asking specific questions. Some b-schools offer application fee waivers if you attend certain events. Keep attending events up to your deadlines — late sessions often cover application tips directly from admissions and are useful for getting clarifications on application logistics, related to references, test score submissions, transcripts etc."
},
{
label: "TOEFL / IELTS", cat: "appreq",
bars: [1,1,1,1,1,1,0,0,0,0,0,0],
dim: [1,1,1,0,0,0,0,0,0,0,0,0],
tip: "International applicants — don't leave it late",
detail: "If you are an international applicant, check each school's English proficiency requirement. Some schools waive the requirement if your undergrad was taught in English, but verify this per school. Although the test itself may not require extensive preparation, don't leave it until the last minute, as test slots fill up and you may not be able to apply in your preferred round without a valid score."
},
{
label: "Profile building", cat: "profile",
bars: [1,1,1,1,1,1,1,1,1,1,1,1],
dim: [1,1,1,0,0,0,0,0,0,0,1,1],
tip: "Start early — aids waitlist updates too",
detail: "If you plan to strengthen your profile through additional academic, professional, or extracurricular activities, start early. These efforts take time to show impact and should ideally continue throughout the year. Building up on these experiences consistently also helps later if you have been waitlisted and need to provide improvement updates."
},
{
label: "B-school selection", cat: "strategy",
bars: [0,0,0,0,1,1,1,0,0,0,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Applying to the right b-schools is critical",
detail: "Once you have your test scores, shortlist your b-schools. You can split your applications into 3 categories: Reach — dream schools with intense competition; At Par — b-schools where your profile matches the class profile and you are likely to get admission; Safety — your profile is above the class profile and you are more likely to get admission here. In one application year, it's optimum to apply to 5–8 b-schools across these 3 categories. Instead of applying to a larger number of b-schools, submit absolutely the best applications to this number of b-schools."
},
{
label: "Application timing", cat: "strategy",
bars: [0,0,0,0,1,1,1,0,0,0,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Plan your R1 / R2 split early",
detail: "Create a timeline for applications in Round 1. If you start early, you can complete all applications in Round 1, which spans September–October. Some b-schools have early application deadlines followed by Round 1 deadlines within a month. By planning strategically, you can spread your applications to cover maximum target b-schools in Round 1. However, if that feels overwhelming, split your list across Round 1 and Round 2."
},
{
label: "Transcripts", cat: "appreq",
bars: [0,0,0,0,1,1,1,1,0,0,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Follow different requirements of every b-school",
detail: "Contact your undergraduate institution for transcripts. Verify from b-school websites: (1) Does the school require transcripts sent directly by your institution or can you upload a scan initially? (2) Non-English transcripts may need certified translations and a WES evaluation for US schools. (3) Some programs require transcripts from every institution attended, including study-abroad semesters. Many universities require 4–8 weeks to process official transcript requests, so do not leave this until August."
},
{
label: "Goals discovery & essay", cat: "strategy",
bars: [0,0,0,0,1,1,1,1,1,0,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Clarity in career goals is the foundation of a strong application",
detail: "The career goals essay is the most important part of your application, so tackle it before other essays. Spend time clearly defining your short-term and long-term goals. This may require you to talk to other professionals, your managers and colleagues, b-school students and alumni for building a coherent storyline that is ambitious yet realistic."
},
{
label: "Resume", cat: "appmtrl",
bars: [0,0,0,0,1,1,1,0,0,0,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Highlight leadership, quantified achievements and a well-rounded personality",
detail: "Prepare your resume early so that you can share it with current students and hopefully admissions representatives during your research phase. Early feedback helps refine how you present your experiences and achievements."
},
{
label: "Brainstorming & writing essays", cat: "appmtrl",
bars: [0,0,0,0,0,0,1,1,1,0,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Spend enough time on iterations to bring out your personality on paper",
detail: "Create an exhaustive document of your personal and professional experiences. You will use this to brainstorm ideas for your essays. B-schools start releasing essay prompts by June. Start compiling these prompts for your target schools, preferably directly from school websites to ensure that you have the most updated prompts. Reach out to current students again at this stage as you'll need to gather school-specific insights for writing compelling essays. Essay writing is an exhaustive process that requires multiple iterations. Start early so that you can space out your drafts and look at them with fresh eyes."
},
{
label: "Select & contact recommenders", cat: "appmtrl",
bars: [0,0,0,0,0,0,1,1,1,0,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Select recommenders who will wholeheartedly endorse you",
detail: "Connect with your recommenders by July so that they have sufficient time to write strong and thoughtful recommendations before the September deadlines. If need be, follow up with them to remind them."
},
{
label: "Application form", cat: "appmtrl",
bars: [0,0,0,0,0,0,0,1,1,1,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Tell something new about yourself not covered elsewhere",
detail: "Application forms often require extensive information about your work experience, salaries, extracurricular activities, internships, etc. Some forms also include short essays embedded in different sections. Many applicants underestimate the time required. Start filling them early, as leaving them for the last moment creates unnecessary stress, especially if you need to gather documents like transcripts or salary calculations."
},
{
label: "Kira interview prep", cat: "interview",
bars: [0,0,0,0,0,0,0,0,1,1,0,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Perform confidently — 2–3 days prep after submission",
detail: "Once you have submitted your application, you may be asked to complete a video interview, where a prompt appears on your screen and you have to record your answer in real time, without retakes. Practice 2–3 days before, primarily to get comfortable with the format."
},
{
label: "Interview prep", cat: "interview",
bars: [0,0,0,0,0,0,0,0,1,1,1,0],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "Use interviews to differentiate yourself",
detail: "Interview invitations can be released on a rolling basis, sometimes immediately after submission and sometimes up to several weeks later. Given this variability, it is best to begin preparing soon after submitting your applications and practice through mock interviews."
},
{
label: "R1 results", cat: "interview",
bars: [0,0,0,0,0,0,0,0,0,0,1,1],
dim: [0,0,0,0,0,0,0,0,0,0,0,0],
tip: "The sweet taste of success!",
isMilestone: true,
detail: "R1 decisions are typically released in November and December, varying by school. If waitlisted, respond with a concise update letter highlighting recent achievements. If admitted, scholarship and merit award notifications may follow separately; check each school's timeline for fellowship announcements and payment schedules."
}
];
// ── Build filter buttons ─────────────────────────────────────────────────────
const filtersEl = document.getElementById('filters');
const legendEl = document.getElementById('legend');
const labelEl = document.createElement('span');
labelEl.className = 'controls-label';
labelEl.textContent = 'Highlight:';
filtersEl.appendChild(labelEl);
// activeFilter = null means all rows fully visible; a key string means only that cat is highlighted
let activeFilter = null;
let openRow = null;
const btnEls = {};
CATEGORIES.forEach(c => {
const btn = document.createElement('button');
btn.className = 'f-btn';
btn.textContent = c.label;
// Style the button in its category colour from the start
btn.style.background = c.badge;
btn.style.color = c.text;
btn.style.borderColor = c.text;
btn.style.fontWeight = '500';
filtersEl.appendChild(btn);
btnEls[c.key] = btn;
btn.addEventListener('click', () => {
if (activeFilter === c.key) {
// clicking the active filter resets everything
activeFilter = null;
} else {
activeFilter = c.key;
}
applyFilter();
});
// Legend dot
const leg = document.createElement('div');
leg.className = 'leg';
leg.innerHTML = `<div class="leg-dot" style="background:${c.fill}"></div>${c.label}`;
legendEl.appendChild(leg);
});
// "Show all" reset button
const showAllBtn = document.createElement('button');
showAllBtn.className = 'f-btn';
showAllBtn.textContent = 'Show all';
showAllBtn.style.background = 'transparent';
showAllBtn.style.color = 'var(--text-secondary)';
showAllBtn.style.borderColor = 'var(--border-mid)';
showAllBtn.style.fontWeight = '400';
showAllBtn.style.marginLeft = '6px';
filtersEl.appendChild(showAllBtn);
showAllBtn.addEventListener('click', () => {
activeFilter = null;
applyFilter();
});
// Milestone legend entry
const mileLeg = document.createElement('div');
mileLeg.className = 'leg';
mileLeg.innerHTML = `<div class="leg-dot" style="background:var(--cat-interview-text);border-radius:50%"></div>R1 results`;
legendEl.appendChild(mileLeg);
// ── Render all rows once ─────────────────────────────────────────────────────
function buildRows() {
const container = document.getElementById('rows');
container.innerHTML = '';
activities.forEach((act, i) => {
const cat = catMap[act.cat];
const wrapper = document.createElement('div');
wrapper.className = 'row-wrapper';
wrapper.dataset.cat = act.cat; // store cat key for fast filtering
const row = document.createElement('div');
row.className = 'activity-row';
const lbl = document.createElement('div');
lbl.className = 'act-label';
lbl.innerHTML = `<span>${act.label}</span><span class="expand-icon">+</span>`;
row.appendChild(lbl);
for (let m = 0; m < 12; m++) {
const cell = document.createElement('div');
cell.className = 'act-cell';
if (act.bars[m]) {
if (act.isMilestone) {
cell.innerHTML = '<div class="milestone-dot"></div>';
} else {
const bar = document.createElement('div');
bar.className = `bar ${act.cat}${act.dim[m] ? ' dim' : ''}`;
cell.appendChild(bar);
}
}
row.appendChild(cell);
}
const panel = document.createElement('div');
panel.className = 'detail-panel';
const inner = document.createElement('div');
inner.className = 'detail-inner';
inner.innerHTML = `<div class="tip-tag" style="background:${cat.badge};color:${cat.text}">${act.tip}</div><p class="detail-text">${act.detail}</p>`;
panel.appendChild(inner);
row.addEventListener('click', () => {
if (openRow === i) {
panel.classList.remove('open');
row.classList.remove('active');
openRow = null;
} else {
document.querySelectorAll('.detail-panel.open').forEach(p => p.classList.remove('open'));
document.querySelectorAll('.activity-row.active').forEach(r => r.classList.remove('active'));
panel.classList.add('open');
row.classList.add('active');
openRow = i;
}
});
wrapper.appendChild(row);
wrapper.appendChild(panel);
container.appendChild(wrapper);
});
}
// ── Apply filter: fade rows that don't match, highlight active button ────────
function applyFilter() {
// Update row visibility
document.querySelectorAll('.row-wrapper').forEach(w => {
if (activeFilter === null || w.dataset.cat === activeFilter) {
w.classList.remove('faded');
} else {
w.classList.add('faded');
}
});
// Update category button styles
CATEGORIES.forEach(c => {
const btn = btnEls[c.key];
if (activeFilter === null) {
btn.style.background = c.badge;
btn.style.color = c.text;
btn.style.borderColor = c.text;
btn.style.opacity = '1';
} else if (activeFilter === c.key) {
btn.style.background = c.badge;
btn.style.color = c.text;
btn.style.borderColor = c.text;
btn.style.opacity = '1';
} else {
btn.style.background = 'transparent';
btn.style.color = 'var(--text-tertiary)';
btn.style.borderColor = 'var(--border-mid)';
btn.style.opacity = '0.5';
}
});
// Update "Show all" button — highlighted when no filter is active
if (activeFilter === null) {
showAllBtn.style.background = '#f0f0ec';
showAllBtn.style.color = 'var(--text-primary)';
showAllBtn.style.borderColor = 'var(--border-mid)';
showAllBtn.style.fontWeight = '500';
showAllBtn.style.opacity = '1';
} else {
showAllBtn.style.background = 'transparent';
showAllBtn.style.color = 'var(--text-secondary)';
showAllBtn.style.borderColor = 'var(--border-mid)';
showAllBtn.style.fontWeight = '400';
showAllBtn.style.opacity = '1';
}
}
buildRows();
applyFilter();
</script>
</body>
</html>