Calendar: era colours that blend, era look settings, and era info for players - #983
Conversation
Eras gain a second colour, a blend style (gas or ink), an optional own feel, a lore page link, a Director's note and a "hidden until it begins" flag; calendars gain the whole-calendar era look (colours on/off, feel, intensity, speed). Migration 023 (plugin) adds the columns idempotently, with a down file. Players now receive a calendar's eras, filtered server-side: an era hidden until it begins is withheld (name, description, colours, note and the events dated inside it) until the calendar's current date reaches it, and the era before it reads as still going. A Director's note never reaches a player. Lore links a player cannot see are blanked. The boundary is the same as dm_only content: the Owner or a granted co-Director see everything; Scribes and players are filtered. New PUT /calendars/:calid/era-look (Owner) saves the look in one transaction with partial per-era fields. Calendar-format and campaign exports carry the new fields (the lore link by entity slug in campaign export only); the AI export's Safe mode skips secret eras and their events. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
GET /calendars/:calid/eras/:eraID/events (Player+, and the public group) returns the events dated within an era, oldest first, capped at 500 with a total. The era is resolved as the viewer sees it: a player asking for an era still hidden until it begins gets 404, and an era whose end was cleared because a secret era follows runs until the next era the player can see. Events are filtered exactly like the month read (per-user rules, unannounced future events, secret-era events, hidden page links, rule references). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
The eras now show on the calendar itself: - calendar_era_blend.js paints a faint tint of each era's two colours behind the month's days, and a slow curl of colour only at the seam where one era gives way to the next, in the entering era's style (gas mixing or ink in water). A weak device gets a coarser texture at most ~30 frames a second; reduced motion gets a still wash; the motion eases to rest over ~2 s when the tab is hidden, the window loses focus, the pointer leaves or nothing is touched for 8 s, and the loop then stops. When nothing should move it draws once. - The month header's era name is a chip (two with an arrow when an era begins mid-month). Hover or focus shows its dates and length; a press unfolds a panel under the header that pushes the grid down: a ribbon of every era with "you are here" (a segment jumps to the era's first month), then the era's dates, description, lore page, key events (the era's major-tier events, each going to its day) and, for a Director, the private note. Escape, the close button or the chip folds it away. - An era's first day carries a "begins" label that opens the panel. - The era manager moves to an Eras button in the edit strip, and its form gains "hide from players until it begins", the Director's note and a lore page picker. Editing an era no longer resets its colour and order. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
The structure editor (the gear in Edit mode) gains an Era look part with its own Cancel and Save: colours on/off, the overall feel (Still, Slow and subtle, Lively, or Custom from the intensity and speed sliders), and per era the suggested palettes, first and second colour, style (gas mixing or ink in water) and an optional own feel. A small month beside the controls previews each change of era live, painted by the same blend as the calendar. Save sends the whole calendar look and only the era fields that changed; Cancel puts back what was saved. The era manager links to it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
The campaign export round-trip test now carries the era look and the per-era look, lore, DM note and hidden fields, and its fake service implements SaveEraLook. The calendar .ai.md describes eras, the era look part, hidden eras and the era events endpoint. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
…ecret eras boot.js reuses the one calendar_view object, so destroy left a dead painter that the next mount reused: no era colours and a loop nobody could rest. Rule anchors now pass the same secret-era gate as other player event reads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
f5e1d73 to
6c7dbbb
Compare
|
Build & Test and Fresh-DB Migration Replay will be red here, and the cause isn't this PR. Main currently has two core migrations numbered I first carried #977's renumber into this branch. That tripped The fix belongs in #977: either an allowed exception in the guard for a never-deployed renumber, or a different fix. Once #977 lands, I'll merge main into this branch and the checks should go green. Locally, with the stashes migration renumbered for the run only, Generated by Claude Code |
…migration Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0193yvwna56XL2FRDNCMSdT9
The era manager's form now reads like the event editor: the era name,
then When (Starts as month list, day list and year under Month/Day/Year
captions, an Ongoing switch, Ends when it is off, prefilled with where
the era ends now), Details (description, lore page) and Players (the
hide switch, the Director's note). The card grows only to the calendar's
bottom edge and scrolls under a fixed Cancel/Delete/Save bar instead of
hanging over the page. Eras are listed oldest first, one row each, with
the span each really covers (an era with no end runs to the day before
the next begins, so "1000-1523" rather than "1000-present"); an open
form keeps the others in a sideways-scrolling row above it.
Era chip tooltip: pressing a chip re-rendered the chips under a resting
pointer, which fired a fresh mouseover and brought the tooltip back over
the opening panel. A press or Escape now puts it away until the pointer
leaves the chips; focus handed back by Escape stays quiet.
The chip row, not the chip, now takes the -6px left offset: the chip's
negative margin shrank the row's measured width and cut a lone era's
name short ("Age of Drag...").
Era colour field: the coarse canvas is clipped to the outline of the
month's real day cells, and drawn opaque under the clip so scaling up
no longer smears clear pixels into the edge days. Leading and trailing
empty cells stay plain. Tint strength and motion are unchanged.
The era's "begins" label wraps (up to three lines) instead of
truncating, with the era's colour as its left edge; on a phone it is a
"New era" tag in the era's colour, with the full name for screen
readers. The era panel's lore row and the editor's chosen lore page use
an inline page glyph rather than an icon-font glyph, so the box is never
empty. The ribbon's segment tooltip sits under the ribbon, where the
panel's edge no longer cuts it off.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
# Conflicts: # static/css/calendar-view.css # static/js/widgets/calendar_view.js
Requested by Key Maker · project thread
Fixes #923
Security implication:
GET /calendars/:calidand the public route/calendar/erasand/calendarroutesGET /calendars/:calid/eras/:eraID/events.CanAuthorDmOnly;PUT /era-lookneeds Owner.lore_entity_id.Consumer-verified: n/a (the new endpoint's only consumer is
calendar_view.jsin this PR)Mockup: "Era blend" v3 look and v4 settings and info (approved, with option B), https://claude.ai/artifact/1YXz5K4GiPEV6NkytF8uo1. Placement changes per Key Maker's note are on the Sign-offs card "Calendar eras: where the info and the look settings ended up".
What this changes
Before: an era was a name and one colour, which players never saw. The calendar showed nothing where one era turned into the next.
After:
How:
024_era_look(plugin, idempotent, with a down file) adds:ON DELETE SET NULLcalendar_era_blend.jsis a canvas painter shared by the calendar and the settings preview.calendar_view.jsadds the chips, tooltip and inline panel.calendar_era_look.templ,era_look_view.goandcalendar_era_look.jsmake up the settings section. The per-era hidden flag, note and lore page are in the era form (Eras button in Edit).Deviations from the mockup:
Why
#923, from Key Maker's Sign-offs answers on the era blend cards: "i hate this to be just a visual thing", "i'd want my slow and subtle", and "it needs to be something that expands, or hover overs".
Test plan
templ generate(v0.3.1001): no changes.go build ./...OK.go test ./... -short -count=1: 50 packages ok.CHRONICLE_TEST_DB_DSN=... go test ./internal/plugins/calendar/... -count=1: ok, 323 tests. This includes the migration apply-twice and roll-back-twice test, the era repository test and the export round-trip.node --test test/js/*.test.mjs: 323/323, including the newcalendar_era_blend.test.mjs(13).golangci-lint run ./...: 0 issues. All 9tools/check-*.shpass.Tenet self-check
entitiestable through the existing viewable-entities gate.ai.mdcovers the era look, hidden eras and the panel🤖 Generated with Claude Code
https://claude.ai/code/session_01FWwWUo8dgxEwNJ8SWFdJuj
Generated by Claude Code