3.11.0
Released
Features
A completed quest's Quest Chronicle now sits at the top of the quest page, under the quest's header and above its tasks, at every screen size, instead of at the end of the details rail — which on a phone came after every task, so a story you had closed or came back to a week later had to be hunted for. The card shows the story's own title, the opening lines of its first paragraph fading out, and when it was written; Read the Chronicle opens the whole story at once, Replay writes it out again from the first word with the same Skip and reduced-motion behaviour as the first time, and Copy link now copies a link that opens straight into the story. Links ending
?chronicle=reador?chronicle=replayopen the story as the page loads, and are ignored when there is no story or Narrative Mode is off. The quest owner's Regenerate Story moved into the card's ⋯ menu and now asks first, since a new story replaces this one and may use credits. An owner who chose "Maybe later" sees a slim "Your quest is complete. Write its Chronicle?" row with Generate Story in the same place; everyone else sees nothing until there is a story, and the "No story has been generated yet." box is gone. A story that finishes while you keep browsing is announced on the card itself — marked "New", briefly highlighted, with Read it — and the corner prompt appears as well only when the card is scrolled out of view. Who can see a quest's Chronicle is unchanged (#944).Waiting for a Quest Chronicle to be written now looks like a story being written about your quest, instead of five grey bars that never changed. A quill draws a line of ink across a strip of parchment, and the line under it changes every few seconds: "Gathering the tale of your quest…", then "Recounting how you conquered …" for each of your first six completed tasks, then "Choosing the words…" and "Inking the final page…". A note says this usually takes 10–30 seconds, and after 30 seconds it says it is still writing rather than leaving the wait to look like a hang. There is no progress bar, because the story arrives all at once and a bar would be invented. You no longer have to sit and watch: Keep browsing, Escape or a click outside the dialog closes it without stopping the story, the section's button shows "Writing story…" and takes you back to the wait, and when the story lands a "Your Chronicle is ready" prompt appears in the corner with Read it, which opens the word-by-word reveal, and the story on the page is marked "New". If it fails while you are away the prompt says so, with Try again; a failure while you are watching shows in the dialog, whose button now reads Try again, and a request that runs past the route's time limit says the story took too long instead of claiming the server could not be reached. With reduced motion turned on, the quill rests at the end of a finished line. Screen readers hear the opening line and the 30-second update, not a new line every few seconds (#943).
Generating a Quest Chronicle now keeps the dialog open and writes the new story out in it, word by word, as if it were being written right then, instead of closing the dialog and leaving the story at the bottom of the quest's details rail where nothing pointed at it. The dialog widens to a reading view on a parchment background; the story's opening "The Chronicle of …" line is shown as a heading, here and on the quest page, with a drop cap on the first paragraph. The writing pauses briefly at each full stop and longer between paragraphs; a typical story takes about 15–20 seconds and none takes more than 25. Skip, Escape, Space or Enter, or a click on the text shows the rest at once; then Copy link, View on quest page (which closes the dialog and takes you to the story) and Close. Regenerate Story opens the same dialog, waits there while the story is written and reveals the new one the same way, and a failure or a model substitution notice is shown in the dialog. With reduced motion turned on, the story appears complete. Screen readers get the whole story once, not word by word (#942).
Technical changes· 4 entries for database, tooling, CI, tests and docs
Tooling & Configuration
The shared Tailwind preset (
packages/ui/tailwind.config.ts) gained thechronicle-ink,chronicle-quillandchronicle-quill-nibkeyframes and animations for the Chronicle's waiting state. Like the landing demo's, each element's base frame is the reduced-motion frame, and the component pairs every one withmotion-reduce:animate-none(#943).
Tests
chronicle-card.test.tsxis new and covers the card's title heading, the first-paragraph excerpt (and a story with no title line), Read / Replay / Copy link, "Link copied", Regenerate only behind the overflow menu and disabled while writing, the unread state, and the owner's call-to-action row.narrative-panel.test.tsxadds nothing rendered before completion or for a visitor without a story, the owner's Generate Story row, Read showing the story without animation and handing focus back, focus landing on the new card's Read button after a story generated from the row or from Regenerate, Replay restarting the reveal each time and under reduced motion, the card's copy link, Regenerate's confirmation and focus return,?chronicle=read/?chronicle=replayopening the dialog and leaving the address, and the param ignored without a story or with any other value; its #942/#943 tests now regenerate through the menu, find the ready prompt on the card, and check the corner prompt (with a stubbedIntersectionObserver) only for a card scrolled out of view, and its two fallback-model notice tests now wait for the notice, which a slow CI run could check before the reveal reported done.quest-detail-view.test.tsxpins the card under the header and before the tasks and the visitor's task list, outside the rail, and absent with the flag off, before completion for anyone but the owner, and for a visitor or party member without a story;quest-detail-view.layout.test.tspins the same order against the source.lib/quests/chronicle.test.tscoversreadChronicleSearchParam()andchronicleLink().apps/web/e2e/quest-chronicle.spec.tsnow looks for the Chronicle in the main column rather than the rail, finds the ready prompt on the card, and adds a completed quest with a stored story: the card above the tasks, Read, Replay with Skip, and a?chronicle=readlink opening the story (#944).lib/quests/chronicle.test.tscoversbuildChronicleWaitingLines()(quest then tasks then generic lines, no tasks, at most six tasks, blank titles skipped, long titles cut and whitespace collapsed, an untitled quest) andnextChronicleWaitingIndex()going round again from the first task.narrative-panel.test.tsxuses fake timers for the line rotation with and without tasks, the 10–30 second note turning into "still writing" at 30 s, the quill's reduced-motion classes and the absence of skeleton bars, Keep browsing / Escape / backdrop leaving the request running and raising the ready prompt and the "New" marker, Read it opening the reveal and Close returning focus to the section's button, the section's button going back to the wait, a failure while browsing shown as a prompt whose Try again starts over, dismissing the prompt, and a non-JSON 504 reported as too slow.quest-detail-view.test.tsxpins that only the owner is sent the first six completed task titles, andapps/web/e2e/quest-chronicle.spec.tsadds generate → Keep browsing → ready prompt → Read it against a narrative route held back until the dialog is closed. The #942 reduced-motion test now waits for focus to reach Close, which it could check a moment too early under coverage instrumentation, and the dialog's Skip button is keyed so the button that had focus is removed rather than reused as Copy link when the reveal ends (#943).lib/quests/chronicle.test.tscoversparseChronicle()(a title line present, absent, a sentence or a long line in its place, Markdown around it, a heading glued to the first paragraph) and the reveal timing (title first, sentence and paragraph pauses, about 15 s for 250 words and 20 s for 500, the 25 s cap, short stories not slowed down).chronicle-reveal.test.tsxuses fake timers for the word-by-word cadence, the cap, skip by prop and by click, reduced motion, thearia-hiddenlayer beside the full visually hidden text, andonDonefiring once per story.narrative-panel.test.tsxnow covers the dialog staying open after Generate Story, Escape skipping then closing, Space and click skipping, the backdrop, focus moving to Skip and then Close, View on quest page focusing the card, copy link, Regenerate Story's waiting state and reveal, failed and offline attempts shown in the dialog, and the fallback-model notice.apps/web/e2e/quest-chronicle.spec.tsadds generate → reveal → skip → close against a stubbed narrative route, and its existing test now looks for the Chronicle in the details rail, where #753 moved it, rather than the page header. Theapps/webstatements and lines coverage floors rose from 96.0 to 96.1 and functions from 95.8 to 96.0 (measured 96.44 / 96.31) (#942).