Activities
Integrate the embedded activity runtime with reader-owned navigation while respecting its state boundaries.
Activity and quiz pages carry a bundled runtime that renders the interaction, validates answers, and advances the content frame when the learner completes it.
qz001.html<body class="min-h-screen flex items-center justify-center">
<main class="w-full">
<h1 class="sr-only" id="page-heading">Why couldn't Hyena fly?</h1>
<style>
#simple-main {
--quiz-accent: #F89B12;
--quiz-accent-soft: rgba(248, 155, 18, 0.16);
--quiz-header-text: #1F2937;
--quiz-body: #FEF1DE;
--quiz-option: #FFF8EE;
--quiz-option-text: #000000;
--quiz-selected-text: #1F2937;
--quiz-submit: #FABE65;
--quiz-submit-text: #1F2937;
}
#simple-main .quiz-card { background-color: var(--quiz-body); box-shadow: 0 12px 34px rgba(0, 0, 0, 0.10); }
#simple-main .quiz-header { background-color: var(--quiz-accent); }
#simple-main .quiz-question { color: var(--quiz-header-text); }
#simple-main .activity-option {
background-color: var(--quiz-option);
border-color: var(--quiz-accent);
color: var(--quiz-option-text);
box-shadow: 0 6px 0 0 rgba(0, 0, 0, 0.10);
}
/* Quiz options read larger than body copy β the adt-body scale bottoms
out at 16px, which is too small for a tappable answer. Floor at 20px. */
#simple-main .activity-option,
#simple-main .activity-option .option-text {
font-size: 20px;
}
#simple-main .activity-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 0 0 rgba(0, 0, 0, 0.12);
}
#simple-main .activity-option:focus,
#simple-main .activity-option:focus-within {
outline: 3px solid #2563eb;
outline-offset: 2px;
}
#simple-main .activity-option.selected-option {
border-color: var(--quiz-accent);
border-width: 4px;
<!-- β¦ 154 more lines -->The public reference set includes this quiz page in both WebPub and EPUB. It is an excerpt, rather than a complete downloadable fixture, so validate the full interaction against your own package-level test before shipping.
Coordinate with reader chrome
Detect activity pages with [data-section-type^="activity_"]. Your reader can hide the embedded #nav-container, provide its own submit button in the surrounding chrome, and make that button click the embedded one. Track progress by watching the content frameβs location against your reading order.
There is no postMessage contract between the embedded runtime and the host reader.
Keep keyboard focus in the content frame when the reader-owned submit control proxies a click. If the frame does not navigate after submission, leave focus on the activity and expose its validation state there. Treat frame navigation as a fallback signal only; it is not a durable completion API.
Keep state expectations clear
The runtime owns activity state. It persists only free-text answers in the content frameβs localStorage; other answer types reset on reload, and none are exposed to the host reader. Store reader settings yourself, but do not promise durable activity answers unless you build that capability independently.
Activities are practice, not secure assessment
Answer keys are present in the exported page. Do not use this runtime alone for graded or high-stakes assessment.