Skip to content

Instantly share code, notes, and snippets.

@mkhlz
Created March 5, 2026 11:28
Show Gist options
  • Select an option

  • Save mkhlz/e2acff13b909404c3139349219948a63 to your computer and use it in GitHub Desktop.

Select an option

Save mkhlz/e2acff13b909404c3139349219948a63 to your computer and use it in GitHub Desktop.

JS Practical 50 real-world challenges

Enjoy this full spectrum of essential web development topics (Data Structures, Strings, DOM, Events, Storage, OOP, Timers, and Async APIs).

1. data.json

The dummy database file.

{
  "users":[
    { "id": 1, "name": "Alice", "role": "admin", "email": "alice@test.com" },
    { "id": 2, "name": "Bob", "role": "user", "email": "bob@test.com" },
    { "id": 3, "name": "Charlie", "role": "admin", "email": "charlie@test.com" }
  ],
  "products":[
    { "id": 101, "name": "Laptop", "price": 999 },
    { "id": 102, "name": "Mouse", "price": 25 },
    { "id": 103, "name": "Monitor", "price": 200 }
  ],
  "orders":[
    { "id": 1, "userId": 1, "total": 1024 },
    { "id": 2, "userId": 2, "total": 25 }
  ]
}

2. index.html

The UI layout displaying all 50 questions.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ultimate Web Dev Assignment</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <h1>Ultimate Web Developer Assignment</h1>
        <p class="rules"><strong>Rule:</strong> Implement everything from Array methods to DOM manipulation and Promises.</p>
        <div id="score-board">Score: <span id="pass-count">0</span> / 50</div>
    </header>

    <main id="app-container">
        <!-- Arrays & Objects -->
        <div class="question-box" id="q1"><h3>1. Get Admins</h3><p>Write <code>getAdminNames(users)</code>. Return an array of names for users with the 'admin' role.</p></div>
        <div class="question-box" id="q2"><h3>2. Cart Value</h3><p>Write <code>totalCartValue(items)</code>. Items have <code>price</code> and <code>qty</code>. Return the total value.</p></div>
        <div class="question-box" id="q3"><h3>3. Group by Role</h3><p>Write <code>groupByRole(users)</code>. Return an object grouping users by their role.</p></div>
        <div class="question-box" id="q4"><h3>4. Most Expensive</h3><p>Write <code>getMostExpensiveProduct(products)</code>. Return the product object with the highest price.</p></div>
        <div class="question-box" id="q5"><h3>5. Flatten Array</h3><p>Write <code>flattenArray(arr)</code>. Deeply flatten a nested array.</p></div>
        <div class="question-box" id="q6"><h3>6. Remove Duplicates</h3><p>Write <code>removeDuplicates(arr)</code>. Return a new array with no duplicate values.</p></div>
        <div class="question-box" id="q7"><h3>7. Deep Merge</h3><p>Write <code>deepMerge(obj1, obj2)</code>. Return a new object that merges both recursively.</p></div>
        <div class="question-box" id="q8"><h3>8. Deep Clone</h3><p>Write <code>deepClone(obj)</code>. Return a deep copy of the provided object without reference ties.</p></div>
        <div class="question-box" id="q9"><h3>9. Find By Email</h3><p>Write <code>findUserByEmail(users, email)</code>. Return the user object matching the email.</p></div>
        <div class="question-box" id="q10"><h3>10. Sort Products</h3><p>Write <code>sortProductsByPrice(products, order)</code>. Return products sorted by price. Order: 'asc' or 'desc'.</p></div>

        <!-- Strings & Formatting -->
        <div class="question-box" id="q11"><h3>11. Capitalize</h3><p>Write <code>capitalizeWords(str)</code>. Capitalize the first letter of every word.</p></div>
        <div class="question-box" id="q12"><h3>12. Kebab Case</h3><p>Write <code>toKebabCase(str)</code>. Convert "Hello World" to "hello-world".</p></div>
        <div class="question-box" id="q13"><h3>13. Validate Email</h3><p>Write <code>validateEmail(email)</code>. Return true if valid format, false otherwise.</p></div>
        <div class="question-box" id="q14"><h3>14. Extract Mentions</h3><p>Write <code>extractMentions(text)</code>. Return an array of words starting with '@'.</p></div>
        <div class="question-box" id="q15"><h3>15. Format Currency</h3><p>Write <code>formatCurrency(amt, currency)</code>. e.g. formatCurrency(1000, 'USD') -> $1,000.00.</p></div>
        <div class="question-box" id="q16"><h3>16. Truncate Text</h3><p>Write <code>truncateText(text, length)</code>. If longer than length, slice and append '...'.</p></div>

        <!-- DOM & Events -->
        <div class="question-box" id="q17"><h3>17. Create Button</h3><p>Write <code>createButton(text)</code>. Return a new <code>&lt;button&gt;</code> element with the given text.</p></div>
        <div class="question-box" id="q18"><h3>18. Toggle Theme</h3><p>Write <code>toggleTheme(element)</code>. Toggle the 'dark-theme' class on the element.</p></div>
        <div class="question-box" id="q19"><h3>19. Count Children</h3><p>Write <code>countChildElements(element)</code>. Return the number of child elements.</p></div>
        <div class="question-box" id="q20"><h3>20. Click Tracker</h3><p>Write <code>attachClickTracker(btn)</code>. On click, increment <code>btn.dataset.clicks</code>.</p></div>
        <div class="question-box" id="q21"><h3>21. Create List</h3><p>Write <code>createList(items)</code>. Return a <code>&lt;ul&gt;</code> element containing <code>&lt;li&gt;</code>s for each string.</p></div>
        <div class="question-box" id="q22"><h3>22. Form Data to JSON</h3><p>Write <code>getFormData(form)</code>. Parse a form element into a JS object.</p></div>
        <div class="question-box" id="q23"><h3>23. Clear DOM</h3><p>Write <code>removeAllChildren(element)</code>. Safely remove all child nodes.</p></div>
        <div class="question-box" id="q24"><h3>24. Event Delegation</h3><p>Write <code>addDelegatedListener(parent, selector, event, handler)</code>.</p></div>

        <!-- Storage & Web APIs -->
        <div class="question-box" id="q25"><h3>25. Save to Local</h3><p>Write <code>saveToLocal(key, value)</code>. Stringify and save data to localStorage.</p></div>
        <div class="question-box" id="q26"><h3>26. Get from Local</h3><p>Write <code>getFromLocal(key)</code>. Retrieve and parse data from localStorage.</p></div>
        <div class="question-box" id="q27"><h3>27. Parse Query Params</h3><p>Write <code>getQueryParams(url)</code>. Return an object of query string parameters.</p></div>
        <div class="question-box" id="q28"><h3>28. Set Cookie</h3><p>Write <code>setCookie(name, value, days)</code>. Set a cookie expiring in X days.</p></div>
        <div class="question-box" id="q29"><h3>29. Delete Cookie</h3><p>Write <code>deleteCookie(name)</code>. Delete an existing cookie.</p></div>

        <!-- Functions, Closures & OOP -->
        <div class="question-box" id="q30"><h3>30. Counter Closure</h3><p>Write <code>createCounter(init)</code>. Return obj with <code>inc()</code>, <code>dec()</code>, <code>get()</code> methods.</p></div>
        <div class="question-box" id="q31"><h3>31. Curry Addition</h3><p>Write <code>curryAdd(a)</code>. Return a function taking b that returns a + b.</p></div>
        <div class="question-box" id="q32"><h3>32. Memoize</h3><p>Write <code>memoize(fn)</code>. Cache the result of fn based on its argument.</p></div>
        <div class="question-box" id="q33"><h3>33. Compose</h3><p>Write <code>compose(f, g)</code>. Return a function executing g(x), then passing result to f(x).</p></div>
        <div class="question-box" id="q34"><h3>34. Run Once</h3><p>Write <code>once(fn)</code>. Return a function that runs at most once, caching the output.</p></div>
        <div class="question-box" id="q35"><h3>35. User Class</h3><p>Write ES6 <code>UserClass(name, age)</code> with a <code>greet()</code> method returning 'Hi, I am [name]'.</p></div>

        <!-- Timers -->
        <div class="question-box" id="q36"><h3>36. Delay Callback</h3><p>Write <code>delayCallback(cb, ms)</code>. Run the callback after ms.</p></div>
        <div class="question-box" id="q37"><h3>37. Interval Call</h3><p>Write <code>intervalCounter(cb, ms, times)</code>. Call cb repeatedly up to 'times' times.</p></div>
        <div class="question-box" id="q38"><h3>38. Debounce</h3><p>Write <code>debounce(fn, ms)</code>. Delay execution until ms after last call.</p></div>
        <div class="question-box" id="q39"><h3>39. Throttle</h3><p>Write <code>throttle(fn, ms)</code>. Ensure fn is called at most once every ms.</p></div>

        <!-- Promises & Fetch -->
        <div class="question-box" id="q40"><h3>40. Promisify</h3><p>Write <code>promisify(fn)</code>. Convert callback API (data, cb(err, res)) into Promise.</p></div>
        <div class="question-box" id="q41"><h3>41. Sleep</h3><p>Write <code>sleep(ms)</code>. Return a promise that resolves after ms.</p></div>
        <div class="question-box" id="q42"><h3>42. Fetch JSON</h3><p>Write <code>fetchJSON(url)</code>. Fetch and return parsed JSON.</p></div>
        <div class="question-box" id="q43"><h3>43. Fetch Retry</h3><p>Write <code>fetchWithRetry(url, retries)</code>. Retry fetch if failure occurs.</p></div>
        <div class="question-box" id="q44"><h3>44. Fetch Any</h3><p>Write <code>fetchAny(urls)</code>. Return the first successful fetch result using Promise.any.</p></div>
        <div class="question-box" id="q45"><h3>45. Fetch All</h3><p>Write <code>fetchAll(urls)</code>. Return array of all successful fetch results concurrently.</p></div>
        <div class="question-box" id="q46"><h3>46. Fetch Sequentially</h3><p>Write <code>fetchSequentially(urls)</code>. Await each url strictly one by one.</p></div>
        <div class="question-box" id="q47"><h3>47. Timeout Promise</h3><p>Write <code>timeoutPromise(promise, ms)</code>. Reject if promise takes longer than ms.</p></div>
        <div class="question-box" id="q48"><h3>48. Fetch with Auth</h3><p>Write <code>fetchWithAuth(url, token)</code>. Fetch passing Authorization Bearer header.</p></div>
        <div class="question-box" id="q49"><h3>49. Poll Endpoint</h3><p>Write <code>pollForCondition(url, conditionFn, ms)</code>. Poll until conditionFn(data) is true.</p></div>
        <div class="question-box" id="q50"><h3>50. Batch Fetch</h3><p>Write <code>batchFetch(urls, batchSize)</code>. Fetch in chunks to avoid overloading network.</p></div>
    </main>

    <script src="solution.js"></script>
    <script src="tester.js"></script>
</body>
</html>

3. solution.js

The workspace file for the student.

// --- 1. Arrays & Objects ---
function getAdminNames(users) {}
function totalCartValue(items) {}
function groupByRole(users) {}
function getMostExpensiveProduct(products) {}
function flattenArray(arr) {}
function removeDuplicates(arr) {}
function deepMerge(obj1, obj2) {}
function deepClone(obj) {}
function findUserByEmail(users, email) {}
function sortProductsByPrice(products, order) {}

// --- 2. Strings & Formatting ---
function capitalizeWords(str) {}
function toKebabCase(str) {}
function validateEmail(email) {}
function extractMentions(text) {}
function formatCurrency(amt, currency) {}
function truncateText(text, length) {}

// --- 3. DOM & Events ---
function createButton(text) {}
function toggleTheme(element) {}
function countChildElements(element) {}
function attachClickTracker(btn) {}
function createList(items) {}
function getFormData(form) {}
function removeAllChildren(element) {}
function addDelegatedListener(parent, selector, event, handler) {}

// --- 4. Storage & Web APIs ---
function saveToLocal(key, value) {}
function getFromLocal(key) {}
function getQueryParams(url) {}
function setCookie(name, value, days) {}
function deleteCookie(name) {}

// --- 5. Functions, Closures & OOP ---
function createCounter(init) {}
function curryAdd(a) {}
function memoize(fn) {}
function compose(f, g) {}
function once(fn) {}
class UserClass {}

// --- 6. Timers ---
function delayCallback(cb, ms) {}
function intervalCounter(cb, ms, times) {}
function debounce(fn, ms) {}
function throttle(fn, ms) {}

// --- 7. Promises & Fetch ---
function promisify(fn) {}
async function sleep(ms) {}
async function fetchJSON(url) {}
async function fetchWithRetry(url, retries) {}
async function fetchAny(urls) {}
async function fetchAll(urls) {}
async function fetchSequentially(urls) {}
async function timeoutPromise(promise, ms) {}
async function fetchWithAuth(url, token) {}
async function pollForCondition(url, conditionFn, ms) {}
async function batchFetch(urls, batchSize) {}

4. tester.js

The robust testing engine. Designed with careful timeouts, deep equality checks, mocked networks, and detached DOM logic to reliably validate right answers without flaking.

window.addEventListener('load', async () => {
    let passed = 0;
    const total = 50;
    const updateScore = () => document.getElementById('pass-count').innerText = passed;

    // --- MOCK SERVER ENGINE ---
    const originalFetch = window.fetch;
    let retryCounter = 0;
    let pollCounter = 0;

    window.fetch = async (url, options = {}) => {
        const _delay = ms => new Promise(r => setTimeout(r, ms));
        await _delay(5); // Simulate fast network

        const ok = data => ({ ok: true, status: 200, json: async () => data });
        const err = (status, msg) => ({ ok: false, status, json: async () => ({ error: msg }) });

        if (url === '/api/flaky') {
            retryCounter++;
            if (retryCounter < 3) throw new TypeError('Network Error');
            return ok({ success: true });
        }
        if (url === '/api/poll') {
            pollCounter++;
            return pollCounter >= 3 ? ok({ status: 'ready' }) : ok({ status: 'pending' });
        }
        if (url === '/api/auth' && options.headers?.Authorization === 'Bearer xyz') {
            return ok({ authorized: true });
        }
        if (url.includes('/api/batch')) {
            await _delay(20);
            return ok({ url });
        }
        if (url.includes('slow')) {
            await _delay(100);
            return ok({ done: true });
        }
        if (url.includes('fast')) {
            return ok({ done: true });
        }
        return ok({ path: url });
    };

    // --- UTILS ---
    const isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
    const delay = ms => new Promise(r => setTimeout(r, ms));

    // --- MOCK DATA ---
    const mockUsers =[
        { id: 1, name: "Alice", role: "admin", email: "alice@test.com" },
        { id: 2, name: "Bob", role: "user", email: "bob@test.com" }
    ];
    const mockProducts =[
        { id: 101, name: "Laptop", price: 1000 },
        { id: 102, name: "Mouse", price: 25 }
    ];

    // --- TEST SUITE ---
    const tests =[
        // Arrays & Objects
        { id: 'q1', run: () => isEqual(getAdminNames(mockUsers), ["Alice"]) },
        { id: 'q2', run: () => totalCartValue([{price: 10, qty: 2}, {price: 5, qty: 1}]) === 25 },
        { id: 'q3', run: () => {
            const res = groupByRole(mockUsers);
            return res.admin.length === 1 && res.user.length === 1 && res.admin[0].name === 'Alice';
        }},
        { id: 'q4', run: () => getMostExpensiveProduct(mockProducts).id === 101 },
        { id: 'q5', run: () => isEqual(flattenArray([1, [2,[3, 4]]]), [1, 2, 3, 4]) },
        { id: 'q6', run: () => isEqual(removeDuplicates([1, 2, 2, 3]),[1, 2, 3]) },
        { id: 'q7', run: () => isEqual(deepMerge({a: 1}, {b: 2}), {a: 1, b: 2}) },
        { id: 'q8', run: () => {
            const obj = { a: { b: 1 } };
            const cloned = deepClone(obj);
            cloned.a.b = 2;
            return obj.a.b === 1;
        }},
        { id: 'q9', run: () => findUserByEmail(mockUsers, "bob@test.com").name === "Bob" },
        { id: 'q10', run: () => sortProductsByPrice(mockProducts, "desc")[0].id === 101 },

        // Strings
        { id: 'q11', run: () => capitalizeWords("hello world") === "Hello World" },
        { id: 'q12', run: () => toKebabCase("Hello World") === "hello-world" },
        { id: 'q13', run: () => validateEmail("a@b.com") === true && validateEmail("ab.com") === false },
        { id: 'q14', run: () => isEqual(extractMentions("Hey @alice and @bob"), ["@alice", "@bob"]) },
        { id: 'q15', run: () => {
            const res = formatCurrency(1000, "USD");
            return res.includes("1,000") && res.includes("$");
        }},
        { id: 'q16', run: () => truncateText("Hello World", 5) === "Hello..." },

        // DOM
        { id: 'q17', run: () => {
            const btn = createButton("Click");
            return btn.tagName === 'BUTTON' && btn.textContent === "Click";
        }},
        { id: 'q18', run: () => {
            const div = document.createElement("div");
            toggleTheme(div);
            return div.classList.contains('dark-theme');
        }},
        { id: 'q19', run: () => {
            const div = document.createElement("div");
            div.innerHTML = "<p></p><span></span>";
            return countChildElements(div) === 2;
        }},
        { id: 'q20', run: () => {
            const btn = document.createElement("button");
            attachClickTracker(btn);
            btn.click(); btn.click();
            return btn.dataset.clicks === "2";
        }},
        { id: 'q21', run: () => {
            const ul = createList(["A", "B"]);
            return ul.tagName === 'UL' && ul.children.length === 2 && ul.children[0].textContent === "A";
        }},
        { id: 'q22', run: () => {
            const form = document.createElement("form");
            form.innerHTML = '<input name="user" value="alice">';
            return getFormData(form).user === "alice";
        }},
        { id: 'q23', run: () => {
            const div = document.createElement("div");
            div.innerHTML = "<p>Text</p>";
            removeAllChildren(div);
            return div.children.length === 0 && div.innerHTML === "";
        }},
        { id: 'q24', run: () => {
            let hit = false;
            const parent = document.createElement("div");
            parent.innerHTML = '<span class="target">A</span><span class="other">B</span>';
            addDelegatedListener(parent, '.target', 'click', () => hit = true);
            parent.querySelector('.other').click();
            if (hit) return false;
            parent.querySelector('.target').click();
            return hit === true;
        }},

        // Storage & APIs
        { id: 'q25', run: () => { saveToLocal('test', {x: 1}); return localStorage.getItem('test') === '{"x":1}'; }},
        { id: 'q26', run: () => { localStorage.setItem('test2', '{"y":2}'); return getFromLocal('test2').y === 2; }},
        { id: 'q27', run: () => getQueryParams("http://a.com?x=1&y=2").x === "1" },
        { id: 'q28', run: () => { setCookie('test_cookie', '123', 1); return document.cookie.includes('test_cookie=123'); }},
        { id: 'q29', run: () => { deleteCookie('test_cookie'); return !document.cookie.includes('test_cookie=123'); }},

        // Closures & OOP
        { id: 'q30', run: () => {
            const c = createCounter(5);
            c.inc(); c.inc(); c.dec();
            return c.get() === 6;
        }},
        { id: 'q31', run: () => curryAdd(5)(10) === 15 },
        { id: 'q32', run: () => {
            let calls = 0;
            const memoed = memoize(x => { calls++; return x * 2; });
            memoed(5); memoed(5);
            return calls === 1 && memoed(5) === 10;
        }},
        { id: 'q33', run: () => compose(x => x * 2, x => x + 1)(5) === 12 },
        { id: 'q34', run: () => {
            let x = 0;
            const runOnce = once(() => ++x);
            runOnce(); runOnce();
            return x === 1;
        }},
        { id: 'q35', run: () => new UserClass("Alice", 25).greet() === "Hi, I am Alice" },

        // Timers
        { id: 'q36', run: async () => { let x=0; delayCallback(()=>x=1, 20); await delay(40); return x===1; }},
        { id: 'q37', run: async () => { let x=0; intervalCounter(()=>x++, 20, 3); await delay(100); return x===3; }},
        { id: 'q38', run: async () => { 
            let x=0; const fn = debounce(()=>x++, 20); 
            fn(); fn(); fn(); await delay(40); return x===1; 
        }},
        { id: 'q39', run: async () => {
            let x=0; const fn = throttle(()=>x++, 30);
            fn(); fn(); await delay(20); fn(); await delay(40); fn();
            return x===2;
        }},

        // Promises
        { id: 'q40', run: async () => {
            const dummyApi = (val, cb) => setTimeout(() => cb(null, val * 2), 10);
            const pApi = promisify(dummyApi);
            return (await pApi(5)) === 10;
        }},
        { id: 'q41', run: async () => {
            const start = Date.now();
            await sleep(30);
            return (Date.now() - start) >= 25; // Tolerance
        }},
        { id: 'q42', run: async () => (await fetchJSON('/api/test')).path === '/api/test' },
        { id: 'q43', run: async () => { retryCounter = 0; return (await fetchWithRetry('/api/flaky', 5)).success === true; }},
        { id: 'q44', run: async () => (await fetchAny(['/api/slow', '/api/fast'])).done === true },
        { id: 'q45', run: async () => (await fetchAll(['/api/fast', '/api/fast'])).length === 2 },
        { id: 'q46', run: async () => {
            let timeline =[];
            const _fetchSequentially = async () => {
                await fetchSequentially(['/api/slow', '/api/fast']);
                timeline.push('done');
            }
            _fetchSequentially();
            await delay(50);
            if(timeline.length > 0) return false; // Should still be waiting on slow
            await delay(100);
            return timeline.length === 1;
        }},
        { id: 'q47', run: async () => {
            try { await timeoutPromise(sleep(100), 20); return false; } 
            catch(e) { return true; }
        }},
        { id: 'q48', run: async () => (await fetchWithAuth('/api/auth', 'xyz')).authorized === true },
        { id: 'q49', run: async () => {
            pollCounter = 0;
            const res = await pollForCondition('/api/poll', data => data.status === 'ready', 10);
            return res.status === 'ready';
        }},
        { id: 'q50', run: async () => {
            const urls =['/api/batch1', '/api/batch2', '/api/batch3'];
            const res = await batchFetch(urls, 2);
            return res.length === 3 && res[2].url === '/api/batch3';
        }}
    ];

    const runAsyncTest = async (id, testFn) => {
        const box = document.getElementById(id);
        try {
            const success = await testFn();
            if (success) { box.classList.add('pass'); passed++; } 
            else { box.classList.add('fail'); console.warn(`Test Failed: ${id}`); }
        } catch (e) {
            box.classList.add('fail');
            console.error(`Test Error in ${id}:`, e);
        }
        updateScore();
    };

    // Run sequentially to prevent shared state interference (especially in DOM/Storage)
    for (const test of tests) {
        await runAsyncTest(test.id, test.run);
    }
});

5. style.css

The responsive UI stylesheet that elegantly arranges 50 challenges.

:root {
    --bg: #f8fafc;
    --card-bg: #ffffff;
    --text: #0f172a;
    --primary: #2563eb;
    --success: #16a34a;
    --error: #e11d48;
}

body { 
    font-family: 'Inter', -apple-system, sans-serif; 
    background: var(--bg); 
    color: var(--text); 
    padding: 20px; 
    margin: 0;
}

header { text-align: center; margin-bottom: 40px; }
h1 { color: var(--primary); margin-bottom: 8px; font-weight: 800; font-size: 2.5rem;}
.rules { color: #475569; font-size: 1.1rem; }

#score-board { 
    background: #0f172a; 
    color: white; 
    padding: 12px 28px; 
    border-radius: 30px; 
    display: inline-block; 
    font-size: 1.4rem;
    font-weight: bold; 
    margin-top: 15px;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}

#app-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
    max-width: 1600px;
    margin: 0 auto;
}

.question-box {
    background: var(--card-bg);
    padding: 20px;
    border-radius: 12px;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
    border-left: 6px solid #cbd5e1;
    transition: transform 0.2s, border-color 0.3s;
    display: flex;
    flex-direction: column;
}

.question-box:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}

.question-box h3 { 
    margin-top: 0; 
    font-size: 1.15rem; 
    color: #1e293b; 
    margin-bottom: 10px;
}

.question-box p { 
    font-size: 0.95rem; 
    line-height: 1.5; 
    color: #475569; 
    margin-bottom: 0;
}

.question-box code { 
    background: #f1f5f9; 
    color: #be185d; 
    padding: 3px 6px; 
    border-radius: 4px; 
    font-size: 0.85rem;
}

/* Dynamic Test States */
.pass { border-left-color: var(--success); }
.fail { border-left-color: var(--error); background-color: #fff1f2; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment