VAKT activities
A VAKT activity is a regulation break: a movement or sensory activity a speller does partway through a lesson. VAKT stands for visual, auditory, kinaesthetic, tactile.
VAKT: Bob likes to do jumping jacks. Let's do 3 of those.
Add one from the VAKT activity button in a section's toolbar. Everything about the block (its colour, its label, and its shape) lives in one place, packages/core/src/vakt.js, so the editor, the viewer, both exporters and both importers stay in sync.
Not a question
A VAKT activity is its own block type, not a question type. The distinction is load-bearing:
- it is addressed to whoever is running the lesson, not to the speller;
- it is never answered and never scored;
- it isn't counted by interactive mode's progress bar, and it appears with a section's material rather than as a step of its own;
- it doesn't appear in the printed footer legend, which names question types.
Question blocks carry answers and print in the legend. Making VAKT a question type would have given it all of that and then required exceptions for each one.
The colour and the label
VAKT activities print in a bright red (#ee1111), the one colour the six question types and the teal spelling block deliberately leave free. The red is hue-0 rather than anything warmer on purpose: an orange or an amber would collide with the Multiple answers question type, which is what pushed that type off burnt orange in the first place.
Every activity is prefixed VAKT:. That prefix is not stored: the block holds the activity alone, and whatever renders it adds the label, exactly the way the spelling block's Spell: works. So one authored string can never carry two prefixes, and the label can be translated on screen while the export keeps its canonical form. Type VAKT: into the field yourself and it's stripped, rather than printed twice.
Unlike a question, where only the prompt is coloured and the answer follows in black, the whole VAKT line is red. It's an instruction to the person running the lesson, and it has to be findable at a glance on a page of black body text.
Images and links
Two optional extras, both off by default:
An image. Use Add image to upload one or search Pixabay or Wikimedia. It's referenced by content hash exactly as an image block's is, so it resolves, uploads and exports through the same path, and it's framed by the same alignment (left / centre / right) and size (small / medium / large / full) toggles, which appear under the picture once there is one.
The defaults differ: an image block starts full width, a VAKT picture starts medium and centred. A VAKT picture illustrates the action rather than carrying the lesson's content, so half width is the right starting point, but an activity whose picture has to be read from across the room, or one that should sit beside the text rather than under it, can say so. A picture whose
sizeoralignis missing or unrecognised falls back to the VAKT defaults, not to an image block's full width.Framing describes the lesson page: the editor, the read-only view, and what's printed. Interactive mode ignores it, for a VAKT picture and an image block alike: there a picture is sized by the reading column so it fills the width on a phone, which is the point of that view.
Links. Each is a
{ url, label? }pair: a video to play, a song, a printable. The label is optional; a link without one shows its address. On screen they're real links, opening in a new tab. On paper, where a link can't be clicked, each prints asLabel — https://addressso the address itself is readable.
Only http:, https: and mailto: links are kept. That's the same rule the comment and bio sanitizers enforce (see Rich text); a lesson's links are authored rather than user-submitted, but they still become real <a href> in a published page and in a Word document. An unsafe or half-typed row is dropped at render time rather than refused as you type, so a URL in progress never destroys what's in the field.
Round trips
| Path | What survives |
|---|---|
| Export/Import JSON | Every supported field, unchanged, the closest thing to a lossless round trip. The importer still drops an unsafe link and a block with no activity in it at all. |
| Export DOCX | The red (via a Word character style), the picture at its own size and alignment, and the links as real hyperlinks. |
| Print PDF | The red, via that same character style; see below. |
| Import DOCX | The activity, its picture and its links, read back off the VAKT: label. The picture's framing is not recovered: it comes back at the VAKT defaults, medium and centred. An image block's is lost the same way (each lands on its own defaults) and for the same reason: mammoth hands back no paragraph alignment, and a printed width can't be told apart from a picture that was simply small. |
The Word character style (S2C VAKT) exists for the same reason the question ones do: mammoth drops run colours, so the PDF path, which renders the docx as HTML, would otherwise print every activity in plain black. See Question blocks and the export pipeline.
The DOCX importer matches on the visible VAKT: label rather than on that style, so a lesson typed by hand in Word imports just as well as one this app printed.
In the MCP server
The MCP server can write VAKT blocks too, as { "type": "vakt", "text": ..., "links": [...] }. They are optional and off by default: the assistant adds them only when you ask for them. When you do, the authoring standard puts one per section, last, after that section's questions, and a lesson with one somewhere else is flagged with a warning (never an error, since a break mid-section is a legitimate thing to want). See Lesson validation.
A block written there may also carry an image from add_image, with the same optional size and align an image block takes; left off, they land on the VAKT defaults above.