---
title: "Quiz Whizz | Interactive Quiz Element for YOOtheme Pro Websites"
description: "Build engaging quizzes in YOOtheme Pro with multiple question types, personality tests, custom results, instant feedback, styling and accessibility built in."
url: "https://www.yoozecase.com/?item_id=27"
date: "2026-10-11T17:52:49+00:00"
language: "en-GB"
---

#  Quiz Whizz

You Puzzle Me

**Latest Version**
1.3.0
**Requires**
Yootheme Pro 5+, Joomla 5+, WordPress 6.5+, PHP 8.1 or newer
**Release date**
11 October 2026
**Made for**
Yootheme Pro, Joomla, Wordpress
**License**
GPL-2.0-or-later
**Price**
€25.00 (incl. 6 months of updates)

 [ 🛒 Get it for Joomla 👍 ](https://yoozecase.lemonsqueezy.com/checkout/buy/619af2cc-dbad-4f5f-a4b7-077383198aeb)

 [ 🛒 Get it for WordPress👍 ](https://yoozecase.lemonsqueezy.com/checkout/buy/6e64967b-1554-47b9-9347-fec95b9dad17)

 [ Demo page ](https://www.yoozecase.com/quiz-whizz-demo)

A powerful YOOtheme Pro quiz element for creating beautiful, interactive quizzes, self-tests and personality quizzes without code.

##  What's new in version 1.3.0

- **Security:** A site-wide limit of 500 stored attempts per hour on both platforms (Joomla had none), counted on the results table, and at most 50 instant contact mails per hour.
- **Changed:** Updates need an activated key. Joomla: the update site carries the key as its Download Key; without an active key Joomla shows "The Download Key is missing" and does not install the update. WordPress: without an active key the update is listed without a download, and the plugin row says how to activate. The quizzes keep working either way.
- **Changed:** WordPress: the licence is checked under the product name yc\_quiz\_whizz with the platform WordPress, the same name as the Joomla edition. Keys activated with 1.2.0 or earlier keep working.
- **Changed:** The licence check asks again once a day for every stored status, so a renewed or re-enabled key comes back by itself. A reply from the licence server that says nothing about the key no longer changes the status.
- **Changed:** The deciding question and the stored answer numbers follow the order in the builder, also when a question without text or with fewer than two answers sits between the others. Statistics stored before 1.3.0 for such a quiz used the old numbering.
- **Changed:** The builder preview says so when the deciding question has no text or too few answers yet.
- **Changed:** WordPress: a new version shows up within the hour, and at once after "Check again" on the Updates screen.
- **Changed:** Licence files: LICENSE.txt carries the full GPL text, the trademark note moved to NOTICE.txt, and the contact address is This email address is being protected from spambots. You need JavaScript enabled to view it..
- **Changed:** Joomla: the licence key is no longer printed in the page source of the options screen.
- **Fixed:** A contact left just after the daily summary had run, for an attempt finished just before it, never reached any summary. The summary now counts by the moment the contact came in.
- **Fixed:** When a finished quiz could not be stored (too many attempts in a short time, a database error), the contact form attached the address to the visitor's previous attempt. It now reports that sending failed.
- **Fixed:** Joomla: two requests at the first page view of a day could both send the daily summary, and a failed mail server lost that day's summary. The run is now claimed by one request, and a failed send is tried again later.
- **Fixed:** Joomla: the link in a notification mail followed the address of the visitor's request. It now uses the site address from the configuration or the one seen in the administrator.
- **Fixed:** Joomla: quiz and outcome titles are cleaned the same way as on WordPress, so encoded markup is never stored as markup.
- **Fixed:** WordPress: one visitor could use up the site-wide limit on stored attempts, and on a busy site the limit never reset.

 ![Quiz Whizz](https://www.yoozecase.com/files/quiz-whizz.png)

 [](#)

 [](#)

---

##  Description

**Meet Quiz Whizz. The quiz element YOOtheme Pro was missing.**

Create engaging quizzes, self-tests, knowledge tests and personality quizzes directly in YOOtheme Pro. No separate quiz builder. No shortcodes. No wrestling with ugly forms or outdated interfaces.

Quiz Whizz gives you everything you need to build quizzes that actually feel like part of your website.

Choose between multiple choice, true or false, multiple answers, image answers, points-based self-tests and personality quizzes. Decide whether visitors get instant feedback or see their results at the end. Let questions move on automatically, shuffle questions and answers, set pass marks and create your own result profiles and score bands.

And because it is a proper YOOtheme Pro element, everything is configured right where you build your page. Pick a style preset, use your theme colours or choose your own accent, customise every button label and make the quiz fit seamlessly into your design.

Quiz Whizz also takes care of the details. Keyboard navigation, screen reader announcements, visible focus states, large touch targets and reduced-motion support are built in.

Need results? Store completed attempts in your own website database, view quiz statistics, collect contact details with consent and export your data to CSV. Or keep everything completely anonymous and let the quiz run entirely in the visitor's browser.

From a fun "How well do you know the web?" quiz to a lead-generating personality quiz or a serious-looking self-test, Quiz Whizz gives you the building blocks. You bring the questions.

**One element. Endless ways to quiz.**

Built for&nbsp, Joomla and WordPress with YOOtheme Pro.

##  Feature request

 ### What is the next feature for this plugin?

Submit your idea or vote on existing ones.

  #### Top voted

   Website (leave empty)

'; } html += ''; if (oc.title) { html += '##### ' + escapeHtml(oc.title) + '

'; } if (oc.text) { html += '' + escapeHtml(oc.text).replace(/\\n/g, '
') + '

'; } html += '

'; } // Auto winner(s) - top N from the already vote-sorted features if (mode === 'auto_winner' || mode === 'both') { var n = oc.winnerCount | 0; if (n '; for (var i = 0; i ' + (w.image_url ? '![](https://www.yoozecase.com/'%20+%20escapeHtml(w.image_url)%20+%20')

' : '') + '' + (i + 1) + '' + '' + escapeHtml(w.title) + '' + '' + getIcon(this.cfg.voteIcon) + ' ' + (w.votes | 0) + '' + ''; } html += ''; } } if (html === '') { this.elOutcome.hidden = true; return; } this.elOutcome.innerHTML = html; this.elOutcome.hidden = false; }; /** * Roadmap view (v3.2.0): renders the items as status columns, in the * canonical status order from cfg.statuses. Each column is an 12. inside \* the existing .yc-fb-list , holding its own inner  of items - \* this keeps the delegated click/change handlers on elList working \* unchanged. Unknown statuses fall back into the "open" column so no item \* can silently disappear. Empty columns are skipped when \* cfg.roadmapHideEmpty is set. \*/ Board.prototype.renderRoadmap = function (items) { var stats = (this.cfg.statuses && this.cfg.statuses.length) ? this.cfg.statuses : \['open', 'planned', 'in\_progress', 'shipped', 'declined'\]; var labels = this.cfg.statusLabels || {}; var groups = {}; var i, st; for (i = 0; i ' + '##### ' + '' + escapeHtml(labels\[sv\] || sv) + '' + arr.length + '' + '

    ' + '' + itemsHtml + '
    ' + '
'; } return html; }; Board.prototype.renderItem = function (f, index) { var disabled = this.cfg.isClosed ? 'disabled' : ''; var voted = f.voted ? ' yc-voted' : ''; var descHtml = f.description ? '' + escapeHtml(f.description).replace(/\\n/g, '
') + '

' : ''; var thumbHtml = f.image_url ? '![](https://www.yoozecase.com/'%20+%20escapeHtml(f.image_url)%20+%20')

' : ''; // Status workflow (v3.0.0): badge for any non-default status. The // roadmap view (v3.2.0) skips the badge - the column already // communicates the status, a badge would be redundant noise. var st = (f.status || 'open'); var labels = this.cfg.statusLabels || {}; var statusBadge = (!this.isRoadmap && st && st !== 'open' && labels[st]) ? '' + escapeHtml(labels\[st\]) + '' : ''; // Design themes (v3.1.0): arena / neon / pixel render extra per-item // furniture - rank number, avatar (image or initials), a "leader" pill // on rank 1, and a "votes" label. Classic/colour themes are untouched. var t = this.cfg.theme || 'light'; var themed = (t === 'arena' || t === 'neon' || t === 'pixel'); var rank = (typeof index === 'number') ? (index + 1) : 0; var rankHtml = '', leaderHtml = '', avatarHtml = '', votesLabel = ''; if (themed) { rankHtml = '' + pad2(rank) + ''; if (rank === 1) { leaderHtml = '' + escapeHtml(this.cfg.leaderLabel || 'Leader') + ''; } if (f.image_url) { avatarHtml = '![](https://www.yoozecase.com/'%20+%20escapeHtml(f.image_url)%20+%20')

'; } else { avatarHtml = '' + escapeHtml(initialsOf(f.title)) + '

'; } votesLabel = '' + escapeHtml(this.cfg.votesLabel || 'votes') + ''; } // Moderation overlay: subtle corner buttons, only when canModerate. // Buttons appear on hover/focus (styled in CSS). Even in customizer // preview we render them when canModerate is true so the moderator // can see what visitors with moderation rights will see. var modHtml = ''; if (this.cfg.canModerate) { var parts = []; var hideTitle = escapeHtml(this.t('hideTitle', 'Hide this feature')); var deleteTitle = escapeHtml(this.t('deleteTitle', 'Delete this feature')); if (this.cfg.allowSoftHide) { parts.push( '' ); } if (this.cfg.allowHardDelete) { parts.push( '' ); } if (parts.length || (this.cfg.statuses && this.cfg.statuses.length)) { var sParts = parts.slice(); if (this.cfg.statuses && this.cfg.statuses.length) { var opts = ''; for (var si = 0; si ' + escapeHtml(sl) + ''; } var setStatus = escapeHtml(this.t('setStatus', 'Set status')); sParts.push( '' ); } modHtml = '' + sParts.join('') + '

'; } } var mediaHtml = themed ? avatarHtml : thumbHtml; return ( '32. ' + leaderHtml + rankHtml + '' + mediaHtml + '' + '##### ' + escapeHtml(f.title) + '

    ' + statusBadge + descHtml + '

    ' + modHtml + '
' ); }; /** * Detects whether a JSON response looks like a CSRF/token rejection. * Two cases: * 1. com_ajax-level rejection (Joomla's auto-token-check on POST): top * level message contains the JINVALID_TOKEN_NOTICE text and HTTP * status is typically 403. * 2. Plugin-level rejection from requireToken(): payload.error === "Invalid token". */ Board.prototype.isTokenError = function (status, raw, payload) { if (status === 403) return true; var hay = ''; try { hay = JSON.stringify(raw || {}) + '|' + JSON.stringify(payload || {}); } catch (e) {} return /invalid (security )?token/i.test(hay); }; /** * Fetch a fresh CSRF token from the server. Updates this.cfg.csrfToken so * the next call (and any future calls in this Board's lifetime) use the * correct one. Cache-bust with a timestamp so no upstream CDN caches the * response. */ Board.prototype.fetchFreshToken = function () { var self = this; var url = this.cfg.ajaxUrl + '&task=token&_=' + Date.now(); return fetch(url, { method: 'GET', credentials: 'same-origin', headers: { 'Accept': 'application/json', 'Cache-Control': 'no-cache' } }) .then(function (r) { return r.json(); }) .then(function (data) { var p = self.unwrapAjax(data); if (p && p.ok === true && typeof p.token === 'string' && p.token.length >= 16) { self.cfg.csrfToken = p.token; return p.token; } throw new Error('No fresh token in response'); }); }; /** * Generic POST-with-token helper. Builds FormData from a plain object, * adds the current token, posts. On 403 / token-error response, fetches a * fresh token and retries exactly once. * * @param {string} task The task name (appended to URL and body) * @param {object} fields Key-value form fields (no token) * @return {Promise} Resolves to the unwrapped payload on success. \* Rejects with Error containing .reason on failure. \*/ Board.prototype.postWithToken = function (task, fields) { var self = this; function attempt(token) { var fd = new FormData(); fd.append('task', task); for (var k in fields) { if (Object.prototype.hasOwnProperty.call(fields, k)) { fd.append(k, fields\[k\]); } } fd.append(token, '1'); return fetch(self.cfg.ajaxUrl + '&task=' + encodeURIComponent(task), { method: 'POST', credentials: 'same-origin', body: fd, headers: { 'Accept': 'application/json' } }).then(function (r) { return r.json().then(function (data) { return { status: r.status, raw: data, payload: self.unwrapAjax(data) }; }); }); } return attempt(this.cfg.csrfToken).then(function (res) { // Success path if (res.payload && res.payload.ok === true) { return res.payload; } // Token rejection? Fetch fresh and retry once. if (self.isTokenError(res.status, res.raw, res.payload)) { return self.fetchFreshToken().then(function (fresh) { return attempt(fresh).then(function (res2) { if (res2.payload && res2.payload.ok === true) { return res2.payload; } var err = new Error( (res2.payload && res2.payload.error) || (res2.raw && res2.raw.message) || self.t('requestFailed', 'Request failed.') ); err.payload = res2.payload || null; throw err; }); }); } // Some other error - surface it var err = new Error( (res.payload && res.payload.error) || (res.raw && res.raw.message) || self.t('requestFailed', 'Request failed.') ); err.payload = res.payload || null; throw err; }); }; Board.prototype.handleSubmit = function () { var self = this; if (isInBuilder()) { this.showStatus(this.t('previewSubmit', 'Preview mode - submissions are disabled in the YOOtheme builder. Try this on the published page.'), 'info'); return; } if (this.cfg.isClosed) { this.showStatus(this.cfg.closedMessage || this.t('votingClosed', 'Voting is closed.'), 'info'); return; } var title = (this.elTitle && this.elTitle.value || '').trim(); var desc = (this.elDesc && this.elDesc.value || '').trim(); // Client-side validation: minimum title length. Server re-validates. var minLen = (this.cfg.minTitleLength | 0) || 2; if (title.length for hide/delete, remember parent + sibling for rollback. var li = btn.closest('li'); var parentEl = li ? li.parentNode : null; var nextEl = li ? li.nextSibling : null; if (li && (action === 'hide' || action === 'delete')) { li.remove(); } btn.disabled = true; var task = action === 'hide' ? 'moderate\_hide' : action === 'delete' ? 'moderate\_delete' : action === 'restore' ? 'moderate\_restore' : ''; if (!task) { btn.disabled = false; return; } this.postWithToken(task, { feature\_id: featureId }) .then(function (payload) { // Success - keep the UI as-is (already removed) and refresh // so vote counts, top box, and hidden-features panel reflect // the new state. self.refresh(); if (self.hiddenOpen) { self.hiddenLoaded = false; // force a refetch self.fetchHiddenFeatures(); } var msg = action === 'delete' ? self.t('deleted', 'Feature deleted.') : action === 'hide' ? self.t('hidden', 'Feature hidden.') : action === 'restore' ? self.t('restored', 'Feature restored.') : self.t('done', 'Done.'); self.showStatus(msg, 'success'); setTimeout(function () { self.hideStatus(); }, 3000); }) .catch(function (err) { // Rollback: re-insert the row if we removed it. if (li && parentEl) { if (nextEl) { parentEl.insertBefore(li, nextEl); } else { parentEl.appendChild(li); } } btn.disabled = false; self.showStatus(err && err.message ? err.message : self.t('modFailed', 'Moderation action failed.'), 'error'); }); }; Board.prototype.handleStatusChange = function (featureId, status, sel) { var self = this; if (!featureId || !status) return; sel.disabled = true; this.postWithToken('moderate\_status', { feature\_id: featureId, status: status }) .then(function () { self.refresh(); var label = (self.cfg.statusLabels && self.cfg.statusLabels\[status\]) ? self.cfg.statusLabels\[status\] : status; self.showStatus(self.tf('statusSet', 'Status: %s', label), 'success'); setTimeout(function () { self.hideStatus(); }, 3000); }) .catch(function (err) { sel.disabled = false; self.showStatus(err && err.message ? err.message : self.t('statusFailed', 'Could not set status.'), 'error'); }); }; /\*\* \* Toggle the hidden-features panel open/closed. First open triggers \* an AJAX fetch; subsequent toggles just hide/show the cached list. \*/ Board.prototype.toggleHiddenPanel = function () { if (!this.elHiddenList || !this.elHiddenLabel) return; var arrow = this.elHiddenToggle && this.elHiddenToggle.querySelector('.yc-fb-hidden-arrow'); if (this.hiddenOpen) { this.hiddenOpen = false; this.elHiddenList.hidden = true; this.elHiddenLabel.textContent = this.t('showHidden', 'Show hidden features'); if (arrow) arrow.classList.remove('yc-open'); return; } this.hiddenOpen = true; this.elHiddenList.hidden = false; this.elHiddenLabel.textContent = this.t('hideHidden', 'Hide hidden features'); if (arrow) arrow.classList.add('yc-open'); if (!this.hiddenLoaded) { this.fetchHiddenFeatures(); } }; /\*\* \* Fetch the hidden-features list via the moderator-only endpoint. \* Re-callable to refresh the list after a restore. \*/ Board.prototype.fetchHiddenFeatures = function () { var self = this; if (!this.elHiddenList) return; this.elHiddenList.innerHTML = '2. ' + escapeHtml(this.t('loading', 'Loading...')) + '
'; var url = this.cfg.ajaxUrl + '&task=moderate\_list\_hidden&board\_id=' + encodeURIComponent(this.cfg.boardId); fetch(url, { credentials: 'same-origin', headers: { 'Accept': 'application/json' } }) .then(function (r) { return r.json(); }) .then(function (data) { var payload = self.unwrapAjax(data); if (!payload || payload.ok !== true) { self.elHiddenList.innerHTML = '4. ' + escapeHtml((payload && payload.error) ? payload.error : self.t('hiddenLoadFailed', 'Failed to load hidden features.')) + '
'; return; } self.hiddenLoaded = true; var features = payload.features || \[\]; if (features.length === 0) { self.elHiddenList.innerHTML = '6. ' + escapeHtml(self.t('noHidden', 'No hidden features.')) + '
'; return; } var html = ''; for (var i = 0; i ' + escapeHtml(f.description).replace(/\\n/g, '
') + '' : ''; var restoreTitle = escapeHtml(self.t('restoreTitle', 'Restore this feature')); html += '9. ' + '' + '##### ' + escapeHtml(f.title) + '

    ' + descHtml + '' + escapeHtml(self.tf('votesMeta', '%s votes', f.votes | 0)) + '' + '

    ' + '' + '
'; } self.elHiddenList.innerHTML = html; }) .catch(function () { self.elHiddenList.innerHTML = '11. ' + escapeHtml(self.t('hiddenNetwork', 'Network error while loading hidden features.')) + '
'; }); }; function initAll(scope) { var roots = (scope || document).querySelectorAll('.yc-fb-root'); for (var i = 0; i ---

##  Changelog

---

 [ v1.3.0 Breaking 11/10/2026 ](#) Changed- Updates need an activated key. Joomla: the update site carries the key as

- WordPress: the licence is checked under the product name yc\_quiz\_whizz
- The licence check asks again once a day for every stored status, so a
- The deciding question and the stored answer numbers follow the order in
- The builder preview says so when the deciding question has no text or
- WordPress: a new version shows up within the hour, and at once after
- Licence files: LICENSE.txt carries the full GPL text, the trademark note
- Joomla: the licence key is no longer printed in the page source of the

 Fixed- A contact left just after the daily summary had run, for an attempt
- When a finished quiz could not be stored (too many attempts in a short
- Joomla: two requests at the first page view of a day could both send the
- Joomla: the link in a notification mail followed the address of the
- Joomla: quiz and outcome titles are cleaned the same way as on
- WordPress: one visitor could use up the site-wide limit on stored

 Security- A site-wide limit of 500 stored attempts per hour on both platforms

 [ v1.2.0 Breaking 29/09/2026 ](#) Added- Image and button per outcome and per score band. Add a picture under the

- Result Element: make the result a heading (H2, H3 or H4), so a screen
- A check in the builder preview. It lists mistakes the builder cannot show:
- A notice in the administrator when the licence key has expired or was

 Changed- The result heading is larger (1.25 times the text size), so it reads as
- The builder lists questions by their text instead of "Question 1",
- "Points A" is now "Points or Weight A", because in a personality quiz the
- Every field in the element has help text, and the short ones say more.
- The plugin description names all three quiz modes.
- The element icon uses the Quiz Whizz colour and the size YOOtheme uses for
- The daily summary holds up to 500 contacts (was 200) and says so when
- The profile bars use the readable variant of the accent.

 Fixed- Two texts in the administrator did not reach the contrast WCAG asks for:
- The dashboard buttons are 44 pixels high, like the other controls.
- Points in the notification mails are written as 12 or 12.5, not 12.00.
- The dashboard shows the newest title of a quiz, not the alphabetically
- French and Italian: a number of texts missed their apostrophe ("n a pas"
- Joomla: the notification mails are written in the default administrator
- Joomla: the daily summary marker is written onto the stored plugin
- Joomla: the token request is never cached, so a page cache cannot hand

 [ v1.1.0 Breaking 29/09/2026 ](#) Added- On A Tie, per quiz. Let One Question Decide looks at a question you pick:

- Tie Text, for your own wording of the line under a tie.
- Profile, per quiz: a bar per outcome with its share of the answers, highest
- Four new strings, in all six languages.

 Changed- When two or more outcomes end with the same total, the result card shows
- A stored tie gets the numbers of all tied outcomes as its key, for example
- The statistics count a tie towards each tied outcome and say how many

 Fixed- An answer linked to an outcome the quiz does not have (outcome 5 in a quiz

 [ v1.0.3 Breaking 07/09/2026 ](#) Changed- Question and answer numbers in the stored answers are the builder order,

 Fixed- The contact form now really waits for the attempt to be stored. submit()
- With Shuffle answers on, the letters A to F are put back in reading order
- A knowledge question without a correct answer (a poll between the test
- A number key pressed on the intro card no longer answers the first question
- A custom accent written as hsl(), a colour name or an eight digit hex now

 [ v1.0.2 Breaking 06/09/2026 ](#) Changed- The Store Results description in the quiz element no longer claims that no

- NOTICE.txt says which of the two storage switches is on after install (the

 Fixed- Saving the plugin options no longer undoes a licence activation. The
- The marker of the last daily summary is now declared in the options form.
- The daily summary window now starts at the moment the previous summary
- The "last checked" moment in the licence panel and the "when" line in the

 [ v1.0.1 Breaking 04/09/2026 ](#) Changed- `NOTICE.txt` said "The plugin makes no external calls". That stopped being

- `TERMS.txt` is no longer part of the package (YC.8). The terms live at
- `PLG\_SYSTEM\_YC\_QUIZ\_WHIZZ\_LIC\_INTRO` already names the Joomla updater in all

 Fixed- The edge of an answer button did not reach 3:1 (WCAG 1.4.11) on a theme
- The Try again button on the result card sat straight against the frame. The
- The licence panel had no edge, fill or radius. The `--yc-qw-\*` custom

 [ v1.0.0 Breaking 02/09/2026 ](#) Added- Licence panel in the plugin settings. Paste a key, activate it, and updates

- The activation slot is released when the plugin is uninstalled, so a key
- Update server and changelog feed, both linked from the manifest, so a new
- TERMS.txt, which says plainly what a subscription buys and what it does not,

 Changed- A licence question never breaks a site. The verdict is cached for a day, and
- Only an HTTP 200 with a parseable body counts as a verdict about a key.
- The licence client is GPL like the rest of the package. Selling it and

 Security- The administrator tasks on the shared AJAX endpoint are refused before

 [ v0.9.2 01/09/2026 ](#) Added- Minified stylesheets and scripts alongside the source. Joomla already asked

 Fixed- The edge that marks a chosen, right or wrong answer now reads at least as

 [ v0.9.1 01/09/2026 ](#) Fixed- A quiz with a custom accent colour got none of the readable colours from

- The colours that carry text are fitted with a little headroom above the
- The answer buttons in the Filled preset had the same faint edge the other

 [ v0.9.0 01/09/2026 ](#) Added- Question Element: the question can be a paragraph, as it always was, or a

 Changed- Answers tell a screen reader what kind of choice they are: one out of several
- The spoken announcement says which question you are on, and no longer says
- The narrow-screen breakpoint moved from 420 to 480 pixels. At 420 a 412
- All direction-dependent styling uses logical properties, so the quiz mirrors
- The contrast maths lives in four pure functions in the engine and is
- The accent keeps its own colour for borders and the focus ring, which need
- The edge colour is behind an @supports check, so a browser without color-mix

 Fixed- A chosen, right or wrong answer now colours its card in every style preset.
- The focus no longer disappears three times. Pressing start, finishing, and
- Text on the accent colour is readable whatever the accent is. White was
- The accent as text has its own colour. The question counter above each
- Passed and failed read at full contrast. The green measured 2.9:1 on a light
- The answers you did not pick stay readable after a question locks. They
- Answer cards have a visible edge. The card fill sat at 1.1:1 against the page

## Schema

```json
{
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [
        {
            "@type": "ListItem",
            "position": 1,
            "name": "Home",
            "item": "https://www.yoozecase.com"
        },
        {
            "@type": "ListItem",
            "position": 2,
            "name": "Extensions",
            "item": "https://www.yoozecase.com/extensions"
        },
        {
            "@type": "ListItem",
            "position": 3,
            "name": "Quiz Whizz",
            "item": "https://www.yoozecase.com/"
        }
    ]
}
```
