Changes since 1.1.0+29:
- build(web): make the sourceMappingURL strip work on BSD sed hosts too (60485c93)
- docs(adrs): accept ADR-0069 (37b578fe)
- docs(adrs): record the lazy brief viewport decision (b55e15d6)
- perf(views): open a large brief through a lazy viewport (3914c96a)
- test(brief): pin the locale variants of a template to the same slots (dca842d4)
- fix(brief): resolve cross-references in names, matching what the app already did (259da342)
- fix(brief): give the summary's rotation line the fix the Organisering block got (d3a77bf6)
- fix(brief): resolve cross-reference tokens in plan.description (2759bd15)
- docs(authoring): state that an override reaches the fields an entity inherits (6ceb9576)
- fix(brief): resolve a cascaded field in the scope it is rendered under (0213daf3)
- docs(adr): generalize ADR-0068 — resolve at the rendering scope, not per field (f1849557)
- docs(adr): close ADR-0068's open question — comms is the only cascading field (c24179ee)
- docs(adr): correct the overstated cost in ADR-0068 (5d4ecc1d)
- docs(adr): accept option A in ADR-0068 — cascaded fields resolve in the borrowing scope (4dcc512b)
- docs(adr): record the cascaded-field vs scoped-override question as ADR-0068 (5afca324)
- fix(share): make the revisit note ring-only, like its twin in the editor (613a3116)
- fix(brief): keep the blank line before a heading when a marker is uncast (0df1b6f6)
- fix(brief): give non-ring round tables a Station column, and keep director notes quoted (398989c6)
- fix(brief): stop the Organisering line calling every exercise a ring route (5c4d43d8)
- fix(brief): read the phase breakdown from the rounds, not from the exercise (2ddc5a68)
- docs(authoring): say that "equipment" is two fields split by audience (2ebc7321)
- fix(schedule): stop a split group's phase overrides being floored at the exercise's (f659a040)
- tools: audit a source document for what analyze cannot see (12ed4494)
- docs(authoring): name the three fields the app asks for, so an agent stops skipping them (f8c4e949)
- feat(views): teach the empty position everywhere it can be empty, not just in one viewer (a7f89f87)
- fix(ios): force 24-hour on the time pickers instead of leaving it to the device (76d9db8e)
- fix(coordinator): stop the expanded card bodies stepping in past their headers (76c63093)
- fix(views): drop the segment icons in compact, from one shared rule (d5b4352f)
- fix(views): make the viewers' card actions ask the edit gate, not just their pencils (2263653a)
- style: format plan_variable_refs_test, which make format-check was failing on (976d98db)
- feat(editor): say when stations have taken over the exercise's phase times (43de52f5)
- feat(station): let a station own all three phase times, not just execution (2402e655)
- style(editor): space the mode selector, and align the group cards with the editors' own (731572cb)
- style(editor): frame the mode selector as a field instead of a bare row (7ea5fc7e)
- fix(editor): state the derived round count instead of disabling the field (465ec2c7)
- fix(brief): darken a table header against the surface it is on, not against white (ac507837)
- docs(authoring): document the exercise modes for skill and MCP authors (7c271bf5)
- fix(brief): fold the round table's suffix into the rotation cell, and fix its header (8dbf4fee)
- feat(editor): lead the exercise preview with the derived round table (63aa168a)
- refactor(l10n): the ring mode is "Ring", so the three read as a set (87a8c98a)
- fix(views): a team held back no longer crashes or invents station "0" (3a43ee38)
- feat(views): put the mode in the card header, and say when a station is unused (5a70e353)
- refactor(views): one mode-aware source for who is at a station in a round (c6a3fdfd)
- fix(picker): drop focus before opening, so a form does not jump back (cd15cbee)
- feat(editor): build the parallel-group editor for split mode (b3cde939)
- feat(editor): choose the exercise mode, and override a station's duration (e96b7604)
- feat(split): author parallel groups and their team assignment (e5f351e6)
- fix(brief): report a station's own duration, and an exercise's real total (93f9da15)
- feat(source): author the exercise mode and a station's own execution time (8948d074)
- feat(schedule): derive rounds from the exercise mode and station durations (48568380)
- docs(adr): accept ADR-0062 (a961a499)
- docs(adr): unequal rounds are a consequence of ADR-0062, not a fourth mode (7ac523bd)
- docs+l10n: the mode is a Ring Route; Ring Drill names the whole domain (2b7bf0e3)
- docs(mockup): title-case the multi-word mode name (d6c8071c)
- docs(adr): make ADR-0062's split general, and its team assignment authored (bb6f9c4e)
- docs(adr): show ADR-0062's schedule as the round table, and put the mockup in English (aad0ce13)
- docs(adr): revise ADR-0062 — a mode and station durations, not a rounds list (d06ce888)
- fix(tokens): let dismissing the menu stick, and leave quoted text alone (fd151826)
- chore(l10n): regenerate the doc comment for tokenBrowserBrowseAll (ad8d489d)
- fix(tokens): open the menu on "/" wherever it is typed, not only after a space (0545febc)
- fix(tokens): pin the browser row to the bottom of the caret menu (f9d421e1)
- docs(adr): accept ADR-0067 — the browser is built (e18faf26)
- feat(tokens): implement the token browser (ADR-0067) (d87d4192)
- feat(picker): let a picker filter by category, as chips or as a master rail (412b7b11)
- docs(adr): pin ADR-0067's shape to the picker primitive, and draw it (472e20e4)
- fix(tokens): replace the token the caret is in, instead of inserting beside it (c2ff7e07)
- docs(authoring): tell agents to promote a repeated literal into a variable (55b862ab)
- docs(adr): reject the team scope — it was a plan variable all along (ADR-0066) (ef4f400f)
- feat(tokens): let the insertion menu card use the width it has (a25b8457)
- fix(tokens): give each rotation phase its own column in the round table (9a9b9e90)
- docs(adr): propose a searchable token browser sheet (ADR-0067) (6dc19e71)
- fix(tokens): stop a long value from consuming a menu row, and name each row's scope (82d65ea6)
- fix(tokens): resolve the new facets in the editor, not only in the brief (699f44e5)
- docs(adr): propose a team scope for the token model (ADR-0066) (62f587e2)
- docs(authoring): point at the new tokens from both guidance surfaces (1e1432e7)
- feat(schema): publish the token inventory the guidance already promised (d1dd0f4f)
- feat(tokens): add the derived values authors were typing by hand (06c23ad3)
- feat(analyze): warn when prose restates the rotation the plan derives (1754cde8)
- docs: track the no-position and plan-overview prompts, and the card mockup (d579c07e)
- fix(views): mark the selected row in the master list (e49446b0)
- feat(brief): add {{exercise.roundTable}}, and tell agents not to hand-roll derived values (58f8959a)
- docs(adrs): close ADR-0063's two per-actor follow-ups as decided, not open (768522d2)
- test(views): verify markdown tables render in the plan overview (80814427)
- fix(views): render plan markdown, tables included, in the overview card (079dc35d)
- fix(views): scroll a wide markdown table instead of overflowing it (7c748565)
- feat(utils): reduce a markdown field to a table-aware plain teaser (03a7e421)
- docs: say when to cache, accept ADR-0049, keep the docx out of the index (ee0ada2b)
- fix(views): size the no-position card to the copy it actually carries (7fc58c8c)
- feat(views): teach the missing position on the markør map surfaces (3df07f02)
- feat(views): teach the missing position on the station map surfaces (17efe5c3)
- feat(views): add a teaching empty state for a missing position (2867a9ec)
- feat(mcp): serve the authoring guide as resources, and the workflow as a prompt (b2315739)
- feat(mcp): hold a document under its content hash, when asked (9814b496)
- feat(mcp): take a document by path, and answer with a summary (089c3311)
- feat(mcp): return instructions at initialize, and name the 80-column trap (9eb42ce6)
- docs(source-format): break markdown fields at sentence ends, not at 80 columns (13528f32)
- docs(adrs): propose shipping the authoring conventions over MCP (ADR-0065) (610d1fb5)
- docs(adrs): accept ADR-0064 and amend ADR-0060's retention requirement (81de2ec7)
- docs(adrs): accept the hosted document cache into ADR-0064, opt-in and hashed (af4d0ffd)
- fix(netlify): move the shared helpers out of the functions root (d0679630)
- docs(adrs): propose cutting the document out of the authoring loop (ADR-0064) (b6eb0be3)
- feat(source): accept a UTM string wherever a position is taken (e915ffbe)
- feat(analyze): validate variable facets, and refuse to build a known-broken plan (2a68317b)
- feat(brief): one audience per staff role, visibility declared on the field (95125102)
- fix(mcp): keep the hosted helpers out of the functions root (ffd6b7fe)
- docs(adrs): keep director_notes, and resolve both gates against five audiences (d46fb5dd)
- test: migrate the last .utm payloads off the removed facet (f5b139bc)
- docs(adrs): accept ADR-0061 (d586b9d3)
- docs(adrs): actors see the cast's contact details too (ADR-0063) (1782a546)
- docs(adrs): accept ADR-0063 (255b5884)
- docs(adrs): actor contact details reach instructors too (ADR-0063) (a83537d2)
- docs(adrs): propose role-aligned brief audiences with per-field visibility (ADR-0063) (417b1290)
- fix(mcp): keep a result key's type the same across outcomes (1c47f342)
- docs(mcp): put the mcp-bundle rule where a compiler change is made (8576d2c4)
- fix(build): run the reference checks under --strict, on both transports (9a7596d3)
- feat(analyze): warn on a scenario-token facet the resolvers do not know (4cdfc3ee)
- test(source): migrate the analyzer's sample tokens off the removed .utm facet (a92c9139)
- fix(tokens): finish the ADR-0050 utm/latlng rename on the editor path (ba67e675)
- docs(source-format): document what a brief actually does with each field (36fe31f4)
- docs(adrs): propose UTM position input and authored rounds (ADR-0061, ADR-0062) (56115655)
- docs(mcp): document the hosted endpoint, and pin test concurrency (0b0de2f6)
- feat(mcp): serve MCP over Streamable HTTP from a Netlify function (ADR-0060) (58419552)
- refactor(mcp): share one tool table between transports (d302afca)
- feat(mcp): cross-compile the source compiler to JavaScript (ADR-0060) (b67babad)
- docs(mcp): document per-client setup, and surface MCP from the root README (3399e50f)
- docs(mcp): document the Cowork and plugin constraints (4e4c0ce3)
- feat(mcp): configure the server from the checkout (eef12f99)
- fix(mcp): exit cleanly when the client closes stdout (dfdde2d8)
- fix(mcp): resolve a CLI that can actually run (43dadb19)
- docs(adr-0060): accept remote MCP hosting (c06f982f)
- docs(adr-0060): propose remote MCP hosting as a Netlify function (7eb0c7e5)
- feat(mcp): make the server easy to run and test locally (188ec697)
- docs(adr-0059): define "rung", the term the ladder is described in (8c0eb3f1)
- refactor(data): finish the ADR-0059 ladder, and accept it (8224f4fd)
- docs(design-014): record what shipped, and make the generators format their output (6e4f61ac)
- feat(mcp): MCP server and authoring skill (DESIGN-014 stage 4) (7492168b)
- feat(source): scaffold a source document with
create(9839b3a6) - feat(brief): render headlessly — the ADR-0048 amendment (DESIGN-014 stage 5) (0ee57be1)
- feat(source): analyze and schema (DESIGN-014 stage 3) (05684424)
- feat(source): decompile to source, and the ADR-0059 migration ladder (stage 2) (954fff38)
- feat(source): compile a source document to .drill (DESIGN-014 stage 1) (18927920)
- docs(design-014): amend the source format spec and add ADR-0059 (c8e44519)
- chore(deps): bump @sentry/node from 10.68.0 to 10.69.0 (d9248aa4)
Changes since 1.0.3+27:
- chore(deps): bump netlify-cli to 27.0.1 and require Node 22.13 (0518d31)
- Update iOS platform to 16.0 and adjust dependencies (1e7696c)
- ci(deps): bump actions/checkout to v7 and actions/cache to v6 (e22013c)
- ci(deps): bump actions/setup-node from 6 to 7 (cf2a78a)
- Remove unused imports across multiple files (1959931)
- chore(deps): clear the function tree's advisories via @netlify/blobs (94d5e1f)
- chore(deps): take the pub minor/patch updates, minus the sentry alpha (ae4f67f)
- fix(shell): pin the rail's role selector to the bottom, fenced by a divider (2667b1c)
- feat(views): teach the empty description cards what belongs in them (3f03132)
- fix(views): the rollup card body was centred and unevenly padded (17ffafd)
- docs(debt): DEBT-0003 is partly paid — the helper exists (03aaaca)
- refactor(netlify): make the PII strip importable so its test covers real code (86c48f7)
- fix(models): keep starting a passed-slot exercise as pending, not done (5082bc0)
- docs(debt): record that an exercise has a time of day but no day (d7408d0)
- docs: add DESIGN-014 and ADR-0058 for the source format and plan compiler (451164c)
- docs: refresh source-format worked example for the landed renames (6ba5906)
- fix(views): stop the schedule summary reporting a negative duration (0cc0e76)
- fix(views): format the pending countdown as a span, not a fabricated instant (06dd040)
- fix(views): show an exercise's real length when it crosses midnight (150147c)
- fix(services): resume an exercise started after midnight instead of waiting a day (1e50ae7)
- test(drill-player): stop the mini player fixtures wrapping past midnight (e40a890)
- feat(views): show progress in the status badge while publishing (5dc11fd)
- fix(views): size each role segment to its label and centre the row (bec4979)
- fix(views): keep the staff role filter on one row at any width (60200fd)
- feat(views): give the staff list the standard row, swipe and long-press (7e7949b)
- fix(views): drop the implied-markør chip, fall back to other on deselect (fe6c308)
- docs: record that StaffRole.other is back, and the mandatory-role rule (9da56ce)
- feat(models): restore StaffRole.other and require a role on every save (98c408f)
- docs: record that markør is stored and StaffRole is the one role enum (9ab0570)
- refactor(models): make StaffRole the one role enum, drop AppUserRole (0d02ebc)
- feat(views): show staff roles as chips and name the posts a member plays (489f0eb)
- docs(adr): amend ADR-0018 for the Staff rename, note the template direction (55aacd2)
- feat(models): generalize Actor into Staff with organizational roles (DESIGN-011) (3ff2079)
- docs(plans): record that account sync puts staff PII on the server (1ce0935)
- fix(netlify): strip both actors/ and staff/ as PII before publishing (02af496)
- docs(views): explain why RingDrillText.forPlan is plain-only (1c52f1c)
- fix(views): name the exercise in the stop-exercise-first snackbars (a330317)
- feat(brief): resolve variables at the exercise and station level, eagerly (db25d38)
- fix(views): route name-bearing snackbars and plan lists through the resolvers (cbfda83)
- feat(views): resolve plan tokens in snackbars and cross-plan text (041db1d)
- refactor(views): delete three unreferenced view files (1818a41)
- refactor(views): move the copy-exercise action into the description card header (626f5cf)
- docs(adr): record the three permission questions in ADR-0057 (13adf0e)
- fix(views): gate the viewer, menu and reorder affordances on the role (f8b2c0c)
- feat(services): split edit permissions into create, edit and delete (e7b6af1)
- test(drill-player): make the mini player fixture start now, not at 10:00 (9d06124)
- feat(views): route every edit affordance through the role gate (7a8c4cc)
- style: format test/ and bin/, and make the formatting rule active (4d12eec)
- style: dart format lib/ (ef82e35)
- docs(adr): accept ADR-0057, role-gated editing (c31548a)
- fix(views): make the role a single source of truth, and match it in the brief (bc71597)
- refactor: finish the synchronous prefs migration (5561d1e)
- refactor: read SharedPreferences synchronously through a shared Prefs service (c2f8f8c)
- feat(views): put the role selector in the drawer header and the rail (70ac36b)
- feat(services): add the Actor role and a single edit-permission matrix (7b6d7cb)
- fix(views): give exercise mode no pager, so the player enters cleanly (e44ebc2)
- feat(views): give the player its own surface, a chevron, and its slide back (0e4a99e)
- feat(views): swipe the player between a target's siblings, wrapping (91e36de)
- refactor(views): delete the superseded exercise-only picker (56d2d58)
- fix(views): pad the picker's search field away from the divider (3df0c8a)
- fix(views): let the player navigate while an exercise is running (8100ed9)
- feat(views): make the player's picker a full navigator, opened by the strip (2fe5091)
- refactor(views): Align widget elements and simplify layout structure. (943733c)
- fix(views): seed the plan scope for the drill player's modes (b674d5b)
- feat(views): add the team screen as a fourth player mode (9009a2d)
- fix(views): read first-frame UI state synchronously, not a frame late (435e8ae)
- fix(views): only adopt a detail selection where a detail pane exists (71f76b4)
- fix(views): reopen a target after closing it, despite a remembered selection (033b7b1)
- docs(adr): record the consolidated player as ADR-0056 (361e56b)
- feat(views): enter the player when opening a live exercise's own items (c486cfe)
- feat(views): make the mini player's badge follow the player's mode (c614479)
- feat(views): make the drill player host any context-sheet target (3d2da96)
- feat(player): host a ContextSheet in the drill player so exercise switches swap in place (fec430a)
- fix(views): don't crash picking an exercise with no open context sheet (c34ee27)
- fix(views): seed the plan facets, not just the variables, at the modal choke points (61713e1)
- fix(views): provide the resolve scopes the coordinator's own content needs (ec0006b)
- feat(views): give the coordinator an Info segment with the exercise description (0dea324)
- fix(views): refresh the coordinator on team changes; add PlanService.reset (8aca115)
- fix(views): refresh the roleplay and station viewers on cast changes (cead7c5)
- refactor(views): adopt Loader in the coordinator and station viewers (7a2537f)
- fix(views): correct the roleplay viewer's exercise identity and missing subject (59e0cec)
- feat(views): add Loader, ClosableSurface and DetailGonePane (4356392)
- fix(l10n): drop the duplicate dismiss key, add gone-state messages (d302244)
- refactor(services): extract PlanService.getExerciseNumber (a557bee)
- docs(adrs): accept ADR-0055 (b0edef0)
- refactor(data): send planId, read it with a programId fallback (ADR-0055) (2494c2b)
- feat(functions): accept planId alongside legacy programId (ADR-0055) (4c66afe)
- feat(functions): add Sentry-tracked legacy-programId telemetry (ADR-0055) (0ec016e)
- test: cover the Plan rename and description field (5bfecdd)
- refactor(models): rename person/roleplay signalement to description (231537d)
- refactor(l10n): Plan labels/keys (e0d46c4)
- refactor(routing): move the /program/ URL namespace to /plan/ (ea017d1)
- refactor(views): rename Program views/controllers/segment to Plan* (18d73d9)
- refactor(services): rename ProgramService/Repository to Plan* (c75c759)
- refactor(models): rename Program to Plan (03de68c)
- docs(prompts): also rename the /program/ URL namespace to /plan/ (90eccd9)
- docs(design): add DESIGN-013 to the index (4c7f24e)
- refactor(views): make the download selector adaptive via showRingdrillPicker (c3d543f)
- refactor(views): rename StationExerciseScreen to StationScreen (2884cef)
- fix(shell): scroll the navigation rail on a short viewport (f3be2b0)
- fix(map): keep every map command reachable on a short landscape viewport (9f06784)
- fix(shell): tidy up the landscape-phone master/detail layout (8d33709)
- fix(shell): reserve the iOS-landscape rail inset so the rail+master row doesn't overflow (5f8624b)
- feat(views): segmented Info/(Script/)Map detail body on compact & medium, with a fill-to-bottom map (5e190e7)
- feat(views): directly-interactive maps with a fullscreen command on medium/expanded detail surfaces (abf7785)
- feat(views): open the context sheet's map/brief viewer as a dialog on wide windows (3fdf196)
- refactor(map): consolidate marker construction into shared builders with number-chip short labels (90a7bba)
- feat(map): viewport-aware camera fit, unbiased centring, zoom-tiered labels and a fullscreen command (8771449)
- docs(adrs): record map camera-fit, viewer-surface, self-fit and interactivity decisions (a2f5bfe)
- fix(views): give each MapView instance its own MapCommand hero tags (b41a812)
- refactor(views): consolidate RolePlaysView into RolePlayListView, mirroring the Station rollup work (c1ef352)
- refactor(views): extract BorderShell; PositionCardShell bar restyle; fix fillHeight+Expanded layout crash (966e444)
- style(views): color the map picker's centre-cross pin green (ee7bed9)
- refactor(views): consolidate SectionRollup/NarrativeRollupCard/NarrativeSectionRollup into Rollup/RollupCard/RollupSection (72ec090)
- refactor(views): merge UtmWidget+LatLngWidget into PositionWidget; drop PositionCardShell's default chevron and tap-opens-sheet behavior (2d7e452)
- feat(views): animate the collapsible section fold and unify cast pills on CastPill (6399f67)
- fix(brief): sanitize tel: dial value and log action-chip launches (23224d2)
- feat(views): collapsible marker position card and auto-address on map pick (80c7ce2)
- refactor(brief): encode action chips as a structured ringdrill://chip URI (b7f03c5)
- docs: reconcile chip and coordinate-facet reference docs with DESIGN-013 (ae8a134)
- feat(views): show the marker phone as an actionable chip in the app and brief (df2f38f)
- docs(prompts): add DESIGN-013 follow-up to use a structured ringdrill://chip URI (cf00405)
- feat(views): render actionable rdchip pills in the app markdown (8266265)
- feat(brief): unify coordinate facets as place + position with a CoordinateFormat seam (5f07a2e)
- feat(views): carry the coordinate on the resolve scopes and resolve app position chips as actionable (d73a374)
- feat(brief): add a per-output-format ChipFormatter strategy (f9a8f56)
- docs(design): add DESIGN-013 and ADR-0050 for actionable field chips (fccb4a5)
- docs: add template and variable reference docs (1bb9989)
- fix(coordinator): close the viewer correctly after deleting its exercise (4caaa7f)
- fix(views): resolve cross-scope tokens in map marker and search labels (b24d24d)
- refactor(views): resolve {{roleplay.*}} via a RoleplayScope, fix cross-scope gaps (d834270)
- refactor(views): split RingDrillText into .plain/.rich and centralise station scope (64a7f39)
- fix(coordinator): resolve {{station.*}} tokens in expanded post cards (b01653a)
- feat(brief): render positions, addresses and phone numbers as copy chips everywhere (6050616)
- fix(brief): keep a coordinate chip and its parentheses on one line (7390327)
- feat: add form-delete for exercises/roleplays and close the event-freshness gaps it exposed (b804145)
- feat(viewers): unified cast pill and person/actor icon convention (DESIGN-012) (11d2859)
- feat(tooling): add headless widget-preview skill (ae3675e)
- fix(shell): defer cross-segment router.go out of the build phase (d21841f)
- feat(viewers): shared map legend, collapsed summaries, and Post-viewer row parity (672cfc4)
- docs: split conventions/glossary/backend/drill-format out of architecture.md (a8a8503)
- test(shell): cover the commit-to-parent form label (c02345d)
- fix(shell): Person/Location forms read commitsToParent in their own chrome (b7c80ab)
- feat(shell): mark nested sub-forms as commit-to-parent (b864db4)
- feat(shell): "Ferdig" label for forms that commit to a parent working copy (602d5dc)
- feat(roleplay): show post and person-location pins on the marker's map (0cd4430)
- feat(roleplay): collapsed section summaries and post numbers everywhere (25d78b9)
- docs(debts): register DEBT-0012 for tap-to-edit gesture leak (a65cece)
- feat(roleplay): tap-to-edit sections and a consolidated PERSON block (a8c66ab)
- feat(roleplay): consolidate the Spill viewer into one Play card (387efa5)
- test(views): cover inline create-from-leaf write-back (00d7782)
- feat(views): apply inline-create additions when a leaf form returns (474dec9)
- feat(views): inline-create write-back from the person form's token fields (9ffe2be)
- feat(views): inline-create write-back from the location form's token fields (5b6aa24)
- test(views): align enacted-person expectations with the cast-actor line (a4e3a48)
- fix(shell): don't clobber a detail deep link when syncing the master segment (a93b8e8)
- docs(prompts): add commit-to-parent form label ("Ferdig") follow-up (cdb7905)
- docs(prompts): add create-from-leaf follow-up (33087ef)
- docs(design): mark DESIGN-010 and ADR-0048 accepted (stage 4 landed) (5c846fc)
- test(views): cover token-aware leaf fields and the self-reference rule (882be5a)
- feat(views): token-aware name, signalement and notes on the person form (1ef52dc)
- feat(views): token-aware place and note on the location form (93a116d)
- fix(shell): narrow the navigation rail back to 72 (22a4172)
- test(shell): master pane survives a collapse toggle without rebuilding (385e801)
- perf(shell): keep the master pane mounted when collapsed so re-expanding is instant (c63faf4)
- docs(prompts): add master-collapse perf fix (1eafb9d)
- fix(views): highlight the selected team for a schedule redirect too (f57bf86)
- fix(views): "Spilles av" names the cast actor, not the person's own name (6a53eb9)
- fix(shell): keep the URL in sync when a redirect switches the master segment (5a46f90)
- fix(design): Changed some icons (daa2bb1)
- fix(views): drop the doubled/dangling divider under a collapsible header (25c2b16)
- test(views): cover Spill card consistency and the revised position collapse (dfe37d7)
- feat(views): fold the Spill person card open to full person info (00515c2)
- feat(views): the Spill post-context card uses the shared collapsible card (f34942d)
- fix(views): rework position-card collapse — title bar, map-overlay chevron (d4190ff)
- fix(shell): open the wide selection properly instead of a raw notifier write (60e344a)
- test(shell): cover master/detail sync on cross-segment redirects (aa21bc3)
- fix(shell): sync the master segment and selection to the detail target (15cc705)
- docs(design): Spill-viewer card consistency, position-collapse rework, master/detail sync (1acbae3)
- fix(views): don't offer position-card collapse in the fill-height pane (d203718)
- fix(views): label the station's own map pin and legend with its name (e4b0c1b)
- test(views): cover collapsible section cards, persistence and the position card (1ce50c0)
- feat(views): collapse the position card to its coordinate row (e3d494c)
- feat(views): fold the titled section cards open and closed (ece3dd6)
- docs(prompts): add DESIGN-010 stage 4 leaf-fields prompt (cff8020)
- feat(views): collapsible section card with a remembered open/closed state (3563a38)
- test(views): cover the filled map height in the Post/Spill expanded layout (bd3e394)
- fix(views): fill the map to full height and align padding in the Post/Spill expanded layout (0fba9d5)
- docs(design-011): accept the person-with-role / Staff ("Stab") model (a4f621a)
- docs(prompts): add Post/Spill map-fill prompt, refine collapsible-cards (87fd798)
- test(views): cover Post/Spill expanded map-right layout (e4bf3b1)
- feat(views): expanded map-right layout for the Spill viewer (a9b1116)
- feat(views): expanded map-right layout for the Post viewer (5abb616)
- docs: add collapsible section cards prompt and position-card mockup (6afa371)
- docs(prompts): add expanded map-right layout for Post and Spill viewers (7983967)
- test(shell): cover per-segment selection memory and the Lag detail leading (f0ae1d9)
- fix(shell): use the shared detail leading in the team (Lag) detail view (c9747a0)
- fix(shell): remember the selected row per segment instead of resetting it (b01ec3f)
- fix(test): pin exercise-service clock in remaining midnight-flaky tests (5bceadf)
- fix(test): pin exercise-service clock in status-card tests to avoid midnight flakiness (e68f697)
- fix(shell): add left-only padding to the master-pane sidebar toggle (a2d4729)
- fix(exercise-service): anchor start/end resolution to avoid a day-rollover crash (40469ca)
- docs(prompts): add collapsible-master-pane follow-up fixes (e05bce5)
- test(shell): cover collapse, persistence, detail leading and auto-select (7b3baa5)
- feat(shell): auto-select the first list item in the wide layout (b5b1788)
- feat(shell): detail sidebar toggle replaces the close button in the wide layout (9c4460f)
- feat(shell): collapsible master pane state, persistence and collapsed layout (9e8f064)
- docs(design): redesign collapsible master pane around the detail leading (c8c6abd)
- test(views): cover the status-card finish-time fallback on the last round (e4d0eb3)
- feat(views): fall back to the exercise finish time when a status-card next-cell is empty (55e2676)
- fix(views): coordinator schedule tables show "Round" not "Schedule" as the header (427279f)
- test(views): coordinator layout tracks its pane width inside master/detail (239c4c4)
- fix(views): coordinator picks its layout from its own pane width, not the window (782894b)
- docs(prompts): add coordinator local-pane-width breakpoint fix (5fa0253)
- test(views): cover status-card polish, coordinator layout and reorder-label fixes (df201a9)
- fix(views): hide the reorder label when nothing is reorderable (ed9ed39)
- feat(views): coordinator play-mode layout for compact, medium and expanded (627836f)
- refactor(views): coordinator reuses the shared status and schedule cards (344c5e0)
- fix(views): consistent padding, bolder meta, roomier first row and centered now/next on the status card (6e16e24)
- docs(design): add coordinator play-mode layout follow-up and breakpoint mockup (b7a5d9b)
- test(views): cover the player status card states and per-role now/next (ab41a9e)
- feat(views): show the status card with role-specific now/next in every player (7aa41ff)
- feat(views): add a shared player status card with pre-start and running states (7d238a6)
- fix(views): use the marker (face) icon on the marker row (4246bd1)
- test(views): cover unified marker management (Fix 4 rework) (3aa0fa1)
- fix(views): unify Poster/Spill marker management on the shared bottom sheet (f61d748)
- docs(prompts): unify marker management via the adaptive selector in the tile polish (5d19076)
- test(views): cover the browser tile polish (758984b)
- fix(views): polish the Poster/Spill browser tiles and resolve station tokens (c124503)
- docs(prompts): add DESIGN-010 browser tile polish + token resolution (ad798ac)
- test(views): cover the coordinator team-detail shared card (eb1d9b2)
- refactor(views): render the coordinator team-detail schedule via the shared card (ff11afd)
- docs(prompts): add DESIGN-010 browser tile polish follow-up (425d08c)
- docs(prompts): add DESIGN-010 3f, coordinator team-detail schedule → shared card (533f332)
- test(views): cover header alignment, uppercase title and the team-screen table (184fca8)
- refactor(views): render the team schedules in the shared schedule card (c7e9665)
- fix(views): center schedule column headers over their times and uppercase the title (7594ce7)
- docs(design-010): add the player status card follow-up and mockup (60d82cd)
- docs(prompts): add DESIGN-010 3e, schedule-table polish (9296129)
- refactor(views): render the team schedule via the shared table (f2d74a8)
- fix(views): restore the coordinator round table's minimized width (2733a1b)
- fix(views): give the schedule table a width mode applied to header and rows (c064e9d)
- docs(prompts): add DESIGN-010 prompt 3d, schedule width mode and team view (21196c1)
- test(views): cover the shared schedule row and table (d721d33)
- refactor(views): render the exercise and team schedules via the shared table (685f7ad)
- feat(views): render the Post/Spill schedule via the shared table (d514e2a)
- feat(views): add a shared schedule table built on the shared row (eac7dde)
- refactor(views): extract a shared schedule row from MiniRoundRow/PhaseWidget (6512a2d)
- docs(prompts): rewrite DESIGN-010 3c to unify the schedule tables (5f352db)
- test(views): cover the Post and Spill viewers (71aecef)
- feat(views): rebuild the Spill viewer as the marker's order (84d6199)
- feat(views): add persons, locations and schedule to the Post viewer (660251a)
- feat(views): rebuild the Post viewer rollup and map cards (b2f26f3)
- test(views): cover full resolution on the read surfaces (2cb6735)
- feat(views): resolve cross-references on the read sheets and lists (2096789)
- feat(views): resolve RingDrillText through the full field resolver (569185d)
- refactor(views): route remaining exercise selectors through the adaptive picker (677ab9e)
- fix(roleplay): backfill identity facets from the linked person on open (e8f9578)
- fix(test): disambiguate the Behaviour tap in reference-integrity test (35489e0)
- refactor(views): route the cast picker through the adaptive picker (e7b2617)
- refactor(views): route the exercise picker through the adaptive picker (337c9c3)
- refactor(roleplay): route Post/Person selection through the adaptive picker (0000f00)
- feat(views): adaptive selector picker (bottom sheet on compact, dialog on wide) (55b695a)
- feat(roleplay): make broken-reference warning chips that open the section (1e495db)
- docs(prompts): split DESIGN-010 stage 3 into 3a and 3b (0d934a7)
- docs(adr): ADR-0049 adaptive selector picker (sheet compact / dialog wide) (2e17aa5)
- fix(roleplay): clear identity fields when switching post (33e74e6)
- feat(editor): post-first roleplay identity + whole-section rollup preview (e7cebbd)
- fix(views): pixel-perfect Post card alignment, correct narrow-width tests (a57196a)
- fix(views): restore right-alignment on the identity Tilpass disclosure (e6e4689)
- fix(views): show markdown section labels in program editor (94e7e71)
- fix(views): show markdown section labels in station/exercise editors (00af8ed)
- fix(views): use InputDecorator so the preview label/text never move (5ba38b4)
- fix(views): match preview's label-to-text gap to the field's own spacing (7b5c785)
- fix(views): align preview text with its label, not the brief-page gutter (40b4c94)
- fix(views): per-section preview must only replace the resolved content (922d073)
- fix(views): stop the Post card and identity disclosure rows overflowing (60cf369)
- fix(views): stop centering short rollup blocks in BriefMarkdownBlock (8600f19)
- test(views): lock rollup indentation parity; investigate fix 2's report (2ec8cf4)
- feat(l10n): label the rollup toggle "Vis/Skjul detaljer" (85e96d1)
- feat(views): enable per-section preview on the base section body (d05943f)
- docs(prompts): add DESIGN-010 prompt 2b, preview and rollup fixes (3fd7c9f)
- test(views): cover preview resolution, the toggle and the rollup (5326846)
- feat(views): read-only section rollup under the default section (8d5fe82)
- feat(views): per-section preview toggle for token-aware fields (7988144)
- feat(views): assemble field-resolver context from the scope cascade (fb7081f)
- docs(prompts): add DESIGN-010 prompt 2, preview and rollup (c2ce9e4)
- test: cover the field resolver and the resolve-scope cascade (20f79a9)
- feat(views): re-provide resolve scopes across openFormSurface (eff0942)
- feat(views): carry program facets on PlanScope and add ExerciseScope (940b67e)
- refactor(brief): extract a reusable field resolver (ADR-0048) (3aad4d3)
- docs(design-010): consolidate to four stages and add the stage 1 prompt (886edaf)
- docs: accept ADR-0047 and DESIGN-009 (scenario locations and persons) (e9a7fc1)
- test: fix locators broken by the section-field label removal (8d7acf9) (4af1275)
- fix(views): use the card position layout everywhere, not just location (9680ee1)
- fix(views): render UTM easting before northing in UtmWidget (68fd1f1)
- test(map): cover UTM and lat,lng resolution in the map search field (f39f69e)
- fix(map): resolve UTM search input by reusing parseCoordinateInput (02d6267)
- fix(views): drop the empty wide section header and the duplicated field label (8d7acf9)
- docs(design-008): align follow-up 11/12 docs and mockups with what shipped (5d1e61f)
- fix(views): give the wide detail pane's ⋮ menu proper header spacing (a7b92d8)
- feat(views): add a search bar to the variable declaration section (856a579)
- fix(views): gate the ⋮ menu behind expansion and make expansion exclusive (616a74e)
- fix(views): un-cram the type-aware fields and swap the type chip for a dropdown (0b128b1)
- fix(views): move the ⋮ menu to the header and the type chip beside the value (8741dae)
- feat(views): redesign variable declaration as collapsible identity-style cards (ad2ff5f)
- docs(prompts): add prompt to reuse parseCoordinateInput in map search (76fbaa5)
- feat(views): tidy the wide section-editor chrome (bcb2f3a)
- feat(views): show variable overrides as cards with inherited value in parentheses (c739e73)
- fix(views): stop IconButton's own min tap target reinflating the field (a5cb574)
- fix(views): align the time/date/duration variable input's icon and value (c7e5cbe)
- docs(adr): record the typed-variables amendment on ADR-0046 (79744e4)
- test: cover variable types, validation, formatting and location facets (8d7927d)
- feat(brief): format typed variables and resolve location facets (21a9773)
- feat(views): render type-aware variable inputs with validation (4390d11)
- feat(model): add a type and location value to plan variables (fc27b5a)
- fix(views): drop the duplicate "Navn" label in the roleplay identity panel (dc6f597)
- docs(design-008): spec typed variables and section-editor polish follow-ups (552211b)
- fix(views): give Persons/Locations cards the app's elevated Card look (cbc5a80)
- fix(views): rename the add-marker action to "Legg til spill" and inline it (c606067)
- fix(views): drop the overflow menu and trim card height in Persons/Locations (02b03d9)
- test(views): cover the roleplay editor refinements and post-editor add-marker (5811150)
- feat(views): card lists and author markers from the post editor's persons section (acb1b7d)
- feat(views): simplify the roleplay identity and position cards (6507b66)
- feat(views): show the roleplay post as a compact card with an edit action (e4fc90d)
- feat(views): give the roleplay editor a static type title (1952fff)
- docs(design-009): refine the roleplay editor and add marker authoring from the post editor (715f232)
- docs(design): specify the Post and Spill viewers as resolved rollups (0f8dc74)
- test(views): cover the loc rename and the roleplay identity/position cards (959f921)
- feat(views): default the roleplay position to the person's location (20d840d)
- feat(views): pack the roleplay identity into an inherit/override card (c5f3d22)
- refactor: rename person location field and facet from home to loc (3640144)
- docs(design-009): add roleplay editor identity/position mockup and prompt 4i (83bd740)
- fix(l10n): relabel the person editor's location field in English too (46ece92)
- fix(l10n): relabel the person editor's empty-location option to Lokasjon (1c8f633)
- feat(views): flag broken scenario references when a roleplay is re-linked (96d5291)
- feat(views): guard location/person deletion while still referenced (b35782a)
- feat(views): block save on unresolved station scenario references (49add0f)
- test(views): assert random, non-derived references (5aa3fda)
- refactor: generate random reference slugs instead of deriving from the name (c2f802a)
- feat(views): reorder the roleplay editor with post first and paired rows (9990553)
- feat(views): pair name+age and relabel the person location field (e3c9ff5)
- refactor(views): single centre pin, dimmed context markers in picker (91d0502)
- docs(prompts): add DESIGN-009 prompt 4h, random reference slugs (9c2b6d5)
- feat(views): map picker confirm in a bottom bar with anchored coordinate (7e05e6f)
- fix(views): square StationMiniMap's bottom corners inside the position card (ab61ca0)
- fix(views): stop PositionCardShell nesting inside an ambient Card (46bdc2d)
- docs(prompts): add DESIGN-009 prompt 4g, person and roleplay editor layout (b033487)
- fix(views): drop the hand-drawn border on PositionCardShell (9a03416)
- docs(prompts): add DESIGN-009 prompt 5, reference integrity (5b51e81)
- refactor(views): station/role position panels on the shared card shell (3800e91)
- refactor(views): extract PositionCardShell shared by the position card (214129f)
- docs(design-010): note stage 4 must migrate direct substitutePlanVariables callers (f65dc18)
- test: cover the station description brief lead and editor collapse (e53da6e)
- docs(design): extend position reflow to read-only detail panels (1092c0c)
- docs(adr-0048): extract a Flutter-free field resolver from BriefRenderer (7a7726b)
- feat(views): collapse the empty station description to an add affordance (14a9f93)
- feat(brief): render the station description as the brief lead paragraph (9ef7109)
- docs(design-009): add prompt 4f, station description as the brief lead (9033c12)
- docs(design-010): fold in the settled scope, naming and rollup decisions (d8c3f8a)
- refactor(views): location form position as single map card with overlay action (41b7815)
- refactor(views): station form position as full-width row, drop 230px box (86e42ea)
- feat(views): PositionFormField row/card variants with thumbnail and tap-to-pick (2de4842)
- test(views): cover facet discovery, completion, home chaining and resolution (d4ee99b)
- feat(views): chain person home to location facets in the picker (309e448)
- feat(views): complete station.loc/person facets in the token picker (b5ee22e)
- docs(design-010): add inline preview and resolve-context scope cascade (1e1f85c)
- docs(prompts): add DESIGN-009 prompt 4d for facet completion (b901d9c)
- fix(views): defer token menu overlay rebuild to a post-frame callback (b2a790b)
- test(views): cover station/roleplay own-facet picker entries and resolution (819d15b)
- feat(views): offer station and roleplay own-facet tokens in their editors (9995c09)
- refactor(views): add station and roleplay own-facet token builders (f861189)
- docs(design-009): specify own-facet, facet-completion and leaf-field follow-ups (7e6ae69)
- test(views): cover plan-field picker entries and their brief resolution (d99347b)
- feat(views): offer program and exercise plan-field tokens in every editor (9d96199)
- refactor(views): add shared program/exercise plan-field token builders (0476ffc)
- docs(prompts): add DESIGN-009 prompt 4b to expose plan-field tokens (19f5dfb)
- test(views): cover station tokens, person binding and inline create/write-back (0ff3e21)
- feat(views): inline-create variables, locations and persons with plan write-back (ef208d2)
- fix(brief): resolve nested {{...}} tokens in markdown fields (a13b456)
- feat(views): bind RolePlay to a Person with inherit/override identity (7ca17a2)
- docs(design): add PositionCard and map picker reflow mockups + prompts (5d80468)
- feat(views): offer station locations and persons in the token picker (e22043b)
- feat(views): add StationScope and station.loc/person token chips (7dd49e8)
- feat(views): pin Variabler last and order Persons above Locations (50ecb7c)
- feat(views): move list search and add-action to one bottom row, drop the sort control (4324fcf)
- feat(views): show the station name as the section header off the base section (77b19fc)
- test: cover Location-form geocoding (forward, reverse, offline-graceful) (2ac02f1)
- feat(views): geocode place in the Location form (forward and reverse) (f98a56a)
- refactor: extract a reusable geocoding service from map search (f8f5708)
- docs: extend DESIGN-009 prompt 3c with editor-UX and ordering refinements (573c4fb)
- test(views): cover auto-reference, form surfaces, gender control and inline home creation (f8f3a19)
- feat(views): full-screen Person form with segmented gender and inline home creation; searchable list (423a5f0)
- feat(views): scenario location/person editor UX and place geocoding (d32723b)
- feat(views): full-screen Location form with category grid and inline position; searchable list (2f37fb7)
- refactor(views): auto-generate location/person reference and drop the manual slug field (ac2e7c0)
- docs(prompts): add DESIGN-009 prompt 4 for picker, RolePlay editor, inline create (cf8b46c)
- docs(prompts): add DESIGN-009 prompt 4 for picker, RolePlay editor, inline create (0b415a8)
- test(views): cover Locations/Persons sections and map markers (05e0070)
- feat(views): show station locations and person homes on the map (352cfc3)
- feat(views): add Locations and Persons sections to the station editor (4427acc)
- feat(l10n): add LocationKind labels and descriptions (d358235)
- docs: align source-format worked example with DESIGN-008/009 model (cf5c917)
- docs(prompts): add DESIGN-009 prompt 3 for sections and map (97a02ae)
- test(services): cover station location/person resolution, facets and effective identity (3393a3b)
- feat(services): resolve station locations and persons in the brief (e7a49f7)
- docs(prompts): add DESIGN-009 prompt 2 for resolution (2dcafaa)
- test(models): cover scenario location/person serialization, backward-compat and hashing (1dcedac)
- feat(models): include scenario locations, persons and roleplay refs in the content hash (7ba0b7b)
- feat(models): add station locations/persons and roleplay personRef/gender (7f9327e)
- feat(models): add Location, Person and LocationKind (9f45819)
- docs(prompts): add DESIGN-009 prompt 1 for model and format (f35d9d7)
- docs(agents): optimize the test loop in rule 9 (913a7a7)
- docs: add source-format worked example for agentic plan generation (2c37241)
- docs: require all documentation to be written in English (bda7c0a)
- docs: add ADR-0047 and DESIGN-009 for scenario locations and persons (b01e8f6)
- test(views): cover title resolution in modal surfaces and the main AppBar (df138e9)
- fix(views): resolve variables in the brief chrome title (eee0b5d)
- fix(views): provide PlanScope inside modal sheets and dialogs (bb52207)
- fix(views): resolve variables in the main tab AppBar title (0abc893)
- docs: DESIGN-008 completion summary (d87b609)
- docs: accept ADR-0046 and DESIGN-008 (df397ce)
- docs(prompts): add DESIGN-008 follow-up 11 for title/modal-scope QA fix (1929ca3)
- test: end-to-end QA pass for DESIGN-008 plan variables (439910d)
- test(views): cover live-UI name resolution and token-aware name fields (12f66e1)
- feat(views): make name and description fields token-aware (773924a)
- feat(views): resolve variables in names and descriptions across the live UI (041c58e)
- feat(views): provide PlanScope around program-scoped routes (7bbc50e)
- feat(views): add RingDrillText read-only variable-resolving text (a8b8ef1)
- test: drop flag-toggle and legacy editor-path tests (8403347)
- chore: remove the RINGDRILL_PLAN_VARIABLES feature flag (841339a)
- refactor(views): drop the flag path from RolePlayFormScreen (e3699dd)
- refactor(views): drop the flag path from StationFormScreen (a6296dc)
- refactor(views): drop the flag path from ExerciseFormScreen (328af4c)
- refactor(views): drop the flag path from ProgramFormScreen (78328c9)
- docs(prompts): add DESIGN-008 final-round prompts and drop the flag from 06/07 (9f43c01)
- test(views): cover station override table and roleplay token fields (1e73cba)
- feat(views): render RolePlayFormScreen as a section-navigated form behind the flag (c8eb4d3)
- feat(views): render StationFormScreen as a section-navigated form behind the flag (5402824)
- fix(views): drop incidental dart_style reformatting from the exercise-form call sites (81fdcfa)
- test(views): cover the exercise override table and token-aware fields (4531702)
- feat(views): render ExerciseFormScreen as a section-navigated form behind the flag (072ed77)
- feat(views): add VariableOverridesSection override table (bed18f7)
- refactor(utils): add shared effectivePlanVariables helper (5578690)
- docs(prompts): add DESIGN-008 follow-up 07 for station/roleplay migration (d2367f7)
- docs(prompts): add DESIGN-008 follow-up 06 for exercise migration + override table (19e7b10)
- test(services): cover variable resolution in names and descriptions (b217d03)
- feat(services): resolve plan variables in brief names and descriptions (ec18e59)
- docs(prompts): add DESIGN-008 follow-up 05 for names/descriptions in brief (53d5f8a)
- docs: record PlanScope and name/description resolution surface in ADR-0046 (e4e3bcf)
- refactor(views): replace MarkdownSectionField with RingDrillTextArea driven by PlanScope (9b81c69)
- feat(views): add RingDrillTextField and RingDrillTextArea reading PlanScope (099bee5)
- feat(views): add PlanScope inherited widget for the active plan's variables (3056ff0)
- refactor(utils): consolidate {{var}} substitution into one shared helper (f18139d)
- fix(views): move the Variabler section to the end of the switcher (2882b08)
- test(views): cover the compact bottom-bar section chrome (ef1cde0)
- feat(views): move compact section controls into a bottom bar (69b78e6)
- docs(prompts): add DESIGN-008 follow-up 04 for a compact bottom bar (e44d349)
- fix(views): keep the section overflow vertical, left of prev/next and stable (b27288d)
- test(views): cover prev/next section navigation (36b4145)
- feat(views): add prev/next section commands to SectionNavigatedForm (2b67f40)
- docs(prompts): add DESIGN-008 follow-up 03 for PlanScope and text widgets (e4f592e)
- docs(prompts): add DESIGN-008 follow-up 02 for prev/next section commands (c77809b)
- test(views): cover variable value editing (2e9115a)
- feat(views): apply variable value edits and refresh token chips (59d122d)
- feat(views): add "Endre verdi" action to the Variabler section (6d1126d)
- docs(prompts): add DESIGN-008 follow-up 01 for variable value editing (ab21578)
- test(views): cover declaration, create-inline, rename, delete and save validation (f08a4ff)
- feat(views): block save on undeclared variable tokens in edited fields (d276ec1)
- feat(views): wire inline create-variable from the insertion menu (206c755)
- feat(views): mount Variabler section in the flag-on Program editor (09681d0)
- feat(views): add Variabler declaration section (9b7d8d5)
- feat(utils): add plan-wide variable reference count, list and rename (d1dbb88)
- docs(design): record the plan-context descendant-addressing open question (54d6aaa)
- feat(services): resolve exercise, station and roleplay data as cross-references (f9953ad)
- feat(views): add ResolvedMarkdownText, the sanctioned way to show plan-scope markdown (a9052b9)
- fix(views): resolve plan variables and cross-references in the Program overview card (250fef8)
- fix(services): resolve {{program.name}}/{{program.description}} inside program-scope fields (fd77a41)
- fix(views): keep the token menu open across "." when typing "{{var." (c4a59cb)
- fix(views): anchor the token insertion menu at the caret, not the field's bounding box (27d4a71)
- docs(prompts): add DESIGN-008 Stage 5 implementation prompt (376fad8)
- test(views): cover token chip states and the insertion menu (858360f)
- feat(views): make MarkdownSectionField token-aware in the flag-on Program editor (2dad9f8)
- feat(views): add slash/brace token insertion menu (bbbcd54)
- feat(views): add token model and TokenTextEditingController (e0f813e)
- docs(notes): record DESIGN-008 token-field prototype gate outcome (e914f80)
- docs(prompts): add DESIGN-008 Stage 4 implementation prompt (c1a7617)
- test(views): cover section navigation, add/remove and flag-off legacy path (928e068)
- feat(views): render ProgramFormScreen as a section-navigated form behind RINGDRILL_PLAN_VARIABLES (0250e65)
- refactor(views): extract MarkdownSectionField shared by both form paths (1876b4f)
- feat(views): add SectionNavigatedForm shell with compact dropdown and wide rail (71672e6)
- docs(prompts): add DESIGN-008 Stage 3 implementation prompt (77ffbba)
- test(services): cover variable resolution, cascade and unknown/empty states (b31988a)
- feat(services): resolve plan variables across program, exercise and station fields (efb67c9)
- feat(services): add variable resolution helpers to BriefRenderer (4452db6)
- feat(l10n): add unknown-variable placeholder string (fc27075)
- docs(prompts): add DESIGN-008 Stage 2 implementation prompt (dcf556c)
- test(views): cover exercise-form override preservation and About page flag default (2dd09f8)
- test(models): cover variable serialization, backward-compat and hashing (a21afa8)
- test(config): update AppFlags.all count for RINGDRILL_PLAN_VARIABLES (c804d3d)
- fix(models): carry variableOverrides through schedule regeneration and content hash (ae627bf)
- feat(models): add variableOverrides to Exercise and Station (15a07fa)
- feat(models): add plan-global variable registry to Program (35a116b)
- feat(models): add DrillVariable (9ec0aa0)
- feat(config): add RINGDRILL_PLAN_VARIABLES feature flag (319cae6)
- fix(catalog): detect station reorders and tidy the Poster divider (244c411)
- feat(catalog): add a deletions toggle and tuck fork into a menu (d968f8a)
- feat(catalog): show local and catalog drill version in the conflict dialog (efbb6be)
- docs(design): plan DESIGN-008 plan variables and section-navigated editor (b7af0f6)
- fix(catalog): make the Plan section use the same colored diff as everything else (2618d4e)
- fix(catalog): match stations by name instead of index for diffing (875091c)
- fix(program): stop stretching the segmented button in the pinned header (dd5c8ec)
- fix(catalog): show per-station diffs with colored inline word-diffs (cf41035)
- feat(catalog): reuse the drag-to-update spinner for the drawer refresh action (5d3c62b)
- fix(forms): return editor save result before the sheet re-opens (b5230f1)
- fix(catalog): fix reversed direction on field-change diffs (e3478c8)
- fix(catalog): tighten the conflict sheet close icon and header padding (040f6f6)
- feat(roster): pull-to-refresh a catalog plan from the Roster tab (6622396)
- fix(catalog): show both positions when an exercise reorders (6764c60)
- fix(catalog): stop calling every name field an exercise name (c9d931c)
- feat(program): pull-to-refresh a catalog plan from anywhere in the segment view (6325bb6)
- fix(catalog): give diff section bodies more contrast against the sheet (80f7b74)
- fix(catalog): actually right-align the conflict dialog actions (98a3557)
- fix(catalog): give each diff section a darker header bar (b6ccbbe)
- fix(catalog): group the conflict dialog actions to the trailing edge (5a73455)
- fix(catalog): tighten the conflict dialog body copy (1bd27af)
- fix(catalog): drop borders on Discard mine and Make a copy buttons (0a75391)
- fix(catalog): move the conflict sheet close icon to the leading position (efedaab)
- fix(catalog): shorten the discard-local-changes button to "Discard mine" (8ae9731)
- fix(catalog): drop the redundant Cancel button, one action row (abcf0f4)
- fix(catalog): group conflict-diff changes per exercise, not by change type (66687e8)
- fix(catalog): make the conflict dialog non-dismissable (60cd906)
- fix(notifications): let users grant iOS permission after first launch (27e3591)
- fix(catalog): show what changed, not just what's named, in the diff (9c9fd66)
- fix(station): stop the position panel from pushing its map icon off-screen (22e9dc6)
- fix(catalog): auto-dismiss the refresh snackbar after showing the result (036159c)
- docs(notes): document the Netlify Blobs Store caching gotcha (5322166)
- fix(catalog): stop caching Netlify Blobs Store instances across invocations (460055d)
- chore(ci): remove the hourly scheduled deploy-origins run (410c658)
- fix(catalog): drills-head never recognized its own primary URL alias (c2c079c)
- fix(catalog): update the refresh snackbar in place instead of closing and reopening (9822b4c)
- fix(catalog): stop misreporting a removed catalog plan as "unavailable" (bf0d9b5)
- fix(catalog): make the refresh loading snackbar non-dismissible with a spinner (457189e)
- Revert "fix(library): show a busy spinner on the row being refreshed from the catalog" (804acfe)
- fix(library): show a busy spinner on the row being refreshed from the catalog (a2b89a1)
- fix(catalog): show a loading hint for the drawer's catalog refresh (2d7e6ae)
- test(position): cover onChanged wiring and drill-file persistence for picked positions (e6daf5f)
- fix(program): make computeContentHash a denylist instead of an allowlist (9176b75)
- fix(map): anchor the marker icon to its box's true bottom edge, not the top (4c73fc5)
- fix(program): include the plan language in the unpublished-changes check (a3c0ef8)
- fix(map): stop marker icons drifting relative to the map when zooming (3221ba1)
- fix(team): update position immediately when picked on the map (75adc4c)
- fix(station): update position immediately when picked on the map (5e798e4)
- fix(station): move the optional-fields divider below the list (fb77510)
- fix(exercise): move the start-time picker beside the exercise name (f76f8c8)
- fix(exercise): add spacing above the optional fields list (fed2d63)
- fix(forms): condense the program editor and fix the exercise divider placement (2562fcd)
- fix(program): hide the optional-fields divider once all fields are added (0b1d9d5)
- fix(program): require a plan language and polish the editor layout (e899232)
- fix(program): shrink the plan-language field to content width (1fbce98)
- fix(roster): give the empty roster a teaching empty state (06b774f)
- fix(library): refuse to delete the currently active plan (f84954f)
- fix(catalog): stop showing two spinners on a busy catalog row (bce42be)
- fix(library): open an already-installed plan when tapped in "Paa nett" (4ac4dd4)
- fix(catalog): show a loading spinner when tapping an uninstalled online plan (1dc5f1d)
- fix(share): reuse the "Legg til øvelser fra..." merge flow for shared-plan Import (15f3517)
- fix(share): show a loading spinner in the Open/Import sheet during install (63f4894)
- fix(share): resolve shared ringdrill.app links instead of corrupting them into fake .drill files (7942ffa)
- fix(preview): favicon href on /i/ pages must be absolute (32b05e7)
- fix(preview): give /i/ share pages the RingDrill favicon (393d189)
- feat(site): add a mobile nav menu so Funksjoner/Katalog/language switch stay reachable (236bdf3)
- fix(site): catalog masonry now fills the shortest column, not balanced halves (6ab4e73)
- fix(site): open the web app in a new tab, not the current one (7ad0645)
- fix(site): replace the Oppdatert/Updated label with a refresh icon (103ae56)
- fix(site): tag-row placeholder height didnt match a real tag rows height (b6d9dd6)
- fix(site): plain-text language label, contain map z-index leak (121fa62)
- fix(site): catalog language filter is a static list, not data-derived (f90dd43)
- fix(site): center the map attribution line above the footer (612b12b)
- fix(site): keep the map frame visible before Leaflet mounts or if it fails (15b65ff)
- feat(site): tag overflow chip, language chip, shrink-to-fit place (3e583e3)
- feat(site): match card height across a map when tag counts differ (2993a57)
- fix(site): catalog language switch stays on the page, add search (a30575c)
- feat(site): share-copied toast, place+meta on one line (ea7eb30)
- feat(site): masonry-style catalog grid, smaller type, share tooltip (ed1f0f5)
- feat(site): catalog card layout pass - 2-col grid, share button, place as tag (0d9218c)
- fix(ci): deploy the site to Cloudflare Workers, not Pages (52fe416)
- fix(site): scope run_worker_first to the on-demand routes only (f71dc6a)
- fix(site): catalog card polish - matching tag colors, bottom-aligned actions, band background (db9b4b1)
- fix(site): force on-demand routes through the Worker on custom domains (c3a2d3a)
- feat(cli): add --functions-base-path and a combined dev-seed target (0bb1255)
- docs(adr): correct ADR-0013 on the CLI functions-base-path gap (d3bcb8a)
- feat(site): render catalog map as a bounding box with a place label (06c5e54)
- feat(netlify): compute mapBounds and reverse-geocode a place name (f9ffd8f)
- docs(adr): supersede centroid-only catalog map with bounding box + place (318f663)
- feat(tools): tag catalog-seed-demos fixtures with real language codes (3b6055b)
- feat(site): add a language filter to /catalog (69b29da)
- feat(netlify): project languageCode in the feed and /i/ preview (f0113d1)
- feat(netlify): read and persist languageCode on publish (353be42)
- feat(views): add plan-language picker to ProgramFormScreen (3609d00)
- feat(models): add languageCode to ProgramMetadata (c4602a5)
- docs(adr): add languageCode addenda to ADR-0007/ADR-0040 and the implementation prompt (cda6c11)
- style(site): match catalog card tags to the /i/ preview design (0c24d3a)
- style(site): show one shared Kartverket attribution per page, not per card (da732f4)
- chore(make): wire site-dev to the local API base (8226926)
- feat(site): add Katalog/Catalog nav link (d0ba3b6)
- feat(site): render /catalog with card grid and map previews (069f9e8)
- feat(site): add catalog data-fetch and pagination helper (5b4173e)
- chore(site): add Cloudflare adapter for on-demand rendering (6743b4d)
- feat(netlify): project mapCenter in the feed (8ba5441)
- feat(netlify): derive and persist mapCenter on publish (f931782)
- docs(adr): add map-center addendum to ADR-0040 and the /catalog implementation prompt (a80cdc2)
- style(views): drop the description line from the "På nett" catalog card (5a85bb4)
- fix(netlify): derive exerciseCount from archive exercise files, not program.json (de0d3a9)
- fix(site): correct App Store links and refresh README CI badges (ad19224)
- feat(data): widen MarketFeedItem with description, exerciseCount, author, accessPolicy (1add311)
- feat(netlify): project description, exerciseCount, author, accessPolicy in feed (221f074)
- feat(netlify): persist exerciseCount, author and accessPolicy on publish (fb1fd0a)
- feat(netlify): add shared meta→feed-item projection in _shared.js (97bc61c)
- refactor(site): surface the /migrate clear action in both states (aa6117c)
- docs(adr): accept ADR-0040 catalog feed schema extension (f8e121e)
- feat(site): add browser-cleanup action and tighten empty state on /migrate (b205395)
- feat(site): add "delete plans from this browser" action to /migrate (0791408)
- i18n(add-exercises): label the selector Legg til, not Import (1066213)
- style(library): match the add-exercises plan list to the open-plan picker (865ca3f)
- docs(adr): accept ADR-0044 render preview on the site (5044ed2)
- docs(adrs): mark ADR-0042 as accepted in index (6d8bb65)
- docs(adr): correct ADR-0044 step 4 for the already-removed _redirects line (93809fc)
- docs(adr): note deploy-origins.yml consolidation in ADR-0039 (de33312)
- ci(deploy): consolidate deploy-{web,pwa,site} into deploy-origins.yml (140fc41)
- docs(adr): correct ADR-0039 proxy mechanism and track cleanup as DEBT-0011 (7231711)
- docs(architecture): correct current .drill schema to 1.2 (07afb64)
- feat(library): list which files were skipped and why in a bundle import (ab88604)
- fix(data): detect .drill entries at any depth so re-zipped bundles still import (ea6d385)
- feat(library): make the import-guide hint explain context and safety, not just the file picker (b65e332)
- feat(library): show a radio in Pa nett for the item matching the active plan (4166a0e)
- fix(library): even out trailing-side padding and clarify the installed chip wording (b6b01c0)
- style(library): even out first/last-row padding and drop the redundant catalog badge in Mine planer (faccf9d)
- fix(library): size leading icons explicitly so card rows do not oversize (6877007)
- style(library): match Mine planer and Pa nett lists to the picker card design (8393421)
- feat(library): give the download-all flow the same name-then-choose steps as download-plan (9d1cf84)
- refactor(library): move Last ned to the library-actions section of the drawer (377bc79)
- feat(library): show source, exercise count and last-updated in the plan picker (9f8b04c)
- style(library): drop the meaningless number badge from the plan picker (b651192)
- style(library): match the plan picker to the exercise picker's card design (0e90f11)
- fix(library): disable exercise picker with a tooltip when a plan has none (f3226ad)
- fix(library): allow exporting/sending a plan with no exercises yet (b9fcaae)
- feat(library): let the user pick which plans to include in a download-all (ace3a0f)
- feat(library): offer a download-all/download-plan chooser from the drawer (25fb7fe)
- test(data): cover DrillLibrary sniff, round-trip and bundle install (2161082)
- feat(router): open the import flow from the ?import=guide deep link (3668859)
- feat(library): add download-all-plans action to the library (6fed25a)
- feat(library): import multi-plan .zip bundles from the file picker (b28ec48)
- feat(l10n): add strings for drill-library import and download-all (bb4a0d4)
- feat(programs): install every plan from a drill-library bundle without activating (ce5c515)
- feat(library): allow picking .zip bundles in the open-file picker (67fee96)
- feat(data): add DrillLibrary bundle format for multi-program archives (db22c04)
- docs(adr): accept ADR-0045 drill library bundle format (a870652)
- docs: add App Store and Cloudflare PWA badges to README (3487512)
- docs(adr): correct ADR-0044 sequencing for the apex-proxy Worker (d2a808b)
- feat(api): interactive API docs and 404s for unknown paths (377f2d0)
- docs(architecture): document site, apex-proxy Worker and origin split (5f44cbe)
- fix(hosting): add apex reverse-proxy Worker for ringdrill.app (6aabd22)
- docs(adr): refine ADR-0044 og:image and cutover sequencing (162f920)
- feat(preview): add og:image share card for link unfurling (b8c0b7a)
- feat(preview): add og:image share card for link unfurling (7d7245b)
- fix(site): only show migration nudge when local plans exist (e599467)
- feat(site): point header CTA to web app instead of Android (4f1cd06)
- feat(site): add iOS App Store download links (1301e2a)
- fix(picker): reuse exercise card styling in the exercise picker (bb0c7a2)
- fix(export): repair .drill export/send from the drawer (421730b)
- fix(models): include tags in content hash and program diff (5c6530d)
- build(web): strip sourceMappingURL comment after deleting maps (629cb3e)
- fix(site): fix btn-primary hover in dark mode — text was invisible (9c8e61a)
- fix(site): improve cache freshness on preview pages (aea60e3)
- fix(site): improve footer layout on narrow viewports (12a5685)
- docs(adr): add ADR-0044 render preview on the site (d617dea)
- docs(adr): mark ADR-0043 accepted and note union→overwrite in AGENTS.md (f7068b2)
- refactor(data): stop sending ?name=/?tags= — plan content travels in program.json (1106d0c)
- feat(netlify): resolve catalog tags from program.json, overwrite on publish (98e714a)
- feat(views): edit plan tags in the Program Editor (3b253a2)
- feat(models): add tags to Program (@Default([]), backward compatible) (985f8e6)
- style: fix static analysis warnings (2de8e09)
- docs(site): clarify SW stub leaves localStorage plans intact (7634b57)
- feat(site): add /migrate page with client-side .drill export (1633355)
- feat(upload): seed catalog name/description from program.json (c748c30)
- feat(site): show migration nudge banner on landing for former apex PWA users (29fdfeb)
- feat(site): serve self-unregister SW stub for retired apex PWA (3889589)
- feat(site): add _headers for .well-known and SW stub (32fef14)
- feat(site): add _redirects for apex proxy and vanity rules (a885aa6)
- feat(upload): seed catalog name/description from program.json (79b091d)
- feat(preview): redesign shared drill preview page (79f842e)
- docs(adr-0039): add Phase 3a follow-up prompt for missing migration mechanics (36b85a1)
- fix(about): point website, privacy and terms links at ringdrill.app (bc56a09)
- refactor(netlify): move tests out of the functions deploy directory (982acfa)
- fix(preview): drop self-referential "Åpne i app" CTA from /i/ (2057b21)
- test(api): cover drills-preview HTML rendering, locale picking and 404 paths (22a8d4f)
- feat(api): interim redirect brief URLs to the new PWA (3583a2a)
- feat(api): route /i/* to drills-preview function (ec4c1f8)
- feat(api): add drills-preview function rendering /i/ HTML in nb and en (69d8051)
- docs(adr-0039): add Phase 3b implementation prompt (ea008c5)
- ci(web): drop Lighthouse audit and CDN-propagation wait from deploy (8e0d2cd)
- fix(install,migration): constrain button width and center in dialogs (cad7594)
- fix(shell): open /install and /migrate via openFormSurface for modal-on-wide (ec9c0e3)
- fix(about): rename About entry to "About RingDrill" and drop redundant title (e3e1f72)
- fix(migration): drop isStandalone gate from isLegacyHost permanently (677873c)
- feat(deploy): activate ADR-0039 migration UI on legacy apex (483701d)
- fix(about): localize developer info section and rename from build flags (803a456)
- docs(notes): add pull-to-refresh list audit (9978a61)
- feat(web): auto-apply pending PWA update on refresh when safe (09ea4f5)
- fix(l10n): state notifications are unsupported on web/PWA (4e60206)
- feat(web): add install guide, migration route and native-app promotion (32cdd0c)
- feat(web): add persistent legacy marker for installed apex PWA (59381ee)
- docs(adr-0039): add Phase 3a implementation prompt (d2c0470)
- fix(client): revert endpoint tails to dash-form to unbreak local dev (c1bd2a0)
- docs(notes): introduce docs/notes/ for episodic findings (5f3c4a0)
- refactor(config): gate local-dev path detection on kDebugMode (f0c4ee7)
- refactor(client): route to public /api/* paths with local-dev fallback (a7fb8ef)
- refactor(client): use public /api/* paths instead of /.netlify/functions/* (84c007a)
- fix(config): route non-apex web hosts to api.ringdrill.app (28beefa)
- fix(web): remove duplicate viewport meta that reintroduced zoom lock (ac12170)
- docs(ops): add wrangler-first Cloudflare setup cookbook for ADR-0039 Phase 2 (1873415)
- ci(site): add Cloudflare Pages deploy workflow for Astro site (3658ac1)
- ci(pwa): add Cloudflare Pages deploy workflow for new PWA (fb1b73a)
- feat(site): complete bilingual landing page and add legal pages (8a84bec)
- feat(site): add .gitignore for build artifacts (6590887)
- feat(site): add bilingual landing pages with download and web CTAs (b09bc2c)
- feat(site): add BaseLayout with hreflang and basic meta (c770327)
- feat(site): copy .well-known files into Astro public directory (0980032)
- feat(site): scaffold Astro project with bilingual i18n routing (fa518ad)
- docs(ops): add Sentry queries cookbook for sunset telemetry and triage (05517c5)
- refactor: rename 'kill switch' to 'feature flag' throughout (20b0612)
- feat(about): restructure Build flags rows with title, subtitle and chip (cafe666)
- refactor(observability): iterate AppFlags list instead of map (1629589)
- refactor(config): make AppFlags entries structured AppFlagInfo (bb9162d)
- docs(adr-0042): switch AppFlags to structured AppFlagInfo with kind and description (4972cd7)
- docs(flags): add living build-flag index and link from README (22028e7)
- feat(about): surface active build flags in the About page (0a47820)
- feat(observability): emit sunset telemetry event when booting on legacy apex (3f285dc)
- feat(observability): tag Sentry scope with build flags and origin (bc32fa2)
- feat(config): centralise build-time feature flags in AppFlags (f7cafbd)
- docs(adrs): propose ADR-0042 feature flags and reserve 0040, 0041 in index (02a5054)
- docs(adr-0039): clarify in phase 2c that deploy-functions.yml waits for phase 3 (d4cb9c4)
- feat(api): allow web.ringdrill.app origin in CORS allowlist (ccb34e1)
- feat(config): point new PWA at api.ringdrill.app via runtime host detection (ae3c298)
- docs(adr-0039): split Phase 2 into 2a/2b/2c sub-prompts (8246db1)
- feat(migration): add MIGRATION_DISABLED kill switch and disable in production (1a11018)
- fix(library): show pick-file errors inline instead of behind the modal (d30a029)
- fix(drill-file): harden parsing for invalid file formats (5318ca7)
- fix(migration): hint banner toward drawer entry for more info (662653e)
- fix(drawer): move "About migration" entry from settings to drawer menu (3fb308a)
- fix(onboarding): tighten web layout and skip OS notification stage on PWA (4053f70)
- fix(migration): render explainer natively and add uninstall step (096a719)
- chore(views): delete backup file (416722d)
- fix(l10n): name the migration target explicitly in settings entry (9b31d29)
- fix(settings): show "About migration" only on legacy apex and move it first (33d43af)
- docs(adr-0039): add Phase 1 implementation prompt (1483618)
- fix(about): make About page scrollable to avoid overflow in wide dialog (b001c77)
- feat(settings): add Om migrasjon page with explainer and re-export action (902bb29)
- feat(shell): add in-app migration banner with export and open-new-app actions (250f7d8)
- feat(data): bulk-export all programs as one ZIP for migration (e612502)
- feat(web): detect when PWA is running on the legacy apex origin (c0a977e)
- docs(adr-0039): accept site/PWA/API origin split (0eff223)
- fix(sentry): attach Dart stack traces to messages and stackless captures (bf4e6ef)
- fix(test): use production router in program_view wide-detail test (40eccd4)
- fix(test): pump segment switcher taps through a GoRouter in program_overview (55a0e18)
- chore(l10n): drop unused exerciseNotifications ARB key (96d33f5)
- fix(notifications): use stable identifier for Darwin notification category (54e215a)
- feat(routing): encode Program-tab segment in URL and route plan activation through go_router (f3081c8)
- refactor(shell): extract WideShell, shell chrome helpers, and snackbars (cd3d0bd)
- feat(player): add exercise picker to DrillMiniPlayer badge (c58fdbd)
- refactor(shell): extract GoRouter config to shell/app_router.dart (a2f1dc9)
- docs(adr-0028): record shell/ and drill_player/ as landed (9b4b2ff)
- refactor(main_screen): extract drawer, deep links, and drill player wiring (32bc447)
- feat(player): show DrillMiniPlayer in station, team, and role views (b454091)
- build: add
make patchfor one-shot Shorebird patching, quiet Sentry uploads (75fb240) - fix(player): scope DrillMiniPlayer to its exercise (052b81d)
- chore(store): add Android phone screenshots in en/nb layout (0e56dbf)
- fix(player): upgrade ContextSheet to fullscreen DrillPlayer on start (aebd25a)
Changes since 1.0.3+26:
- refactor(views): apply tap-row-opens-sheet rule to every expandable (5776b89)
- fix(forms): dismiss context sheet around form route push (b63ac7f)
- chore(ios): bump Runner.xcscheme LastUpgradeVersion to 2660 (04662ab)
- fix(sentry): backstop browser-extension noise in beforeSend (ab5a507)
- chore(ios): pin Runner DEVELOPMENT_TEAM to G2C47B233E (20632ac)
- fix(ios): add NSLocationAlwaysAndWhenInUseUsageDescription (8504a87)
- fix(l10n): handle legacy Norwegian locale
no_NOwithout crashing (4c2e2bf) - fix(make): use awk for release-notes length check, portable on BSD sed (6031b2a)
- chore(release): add
make release-notes, refresh release flow docs (601b134)
Changes since 1.0.3+25:
- build(release): make VERSION optional with interactive prompt (a1eaf54)
- feat(roster): show active plan name in Roster tab header (05cfa09)
- fix(station): compact rotation view at narrow widths (2338c0b)
- fix(map): guard non-finite LatLng at marker producers and in MapView (9d3ae94)
- feat(add-exercises): browse online catalog and merge exercises (64c2d57)
- test: stop tearDown from tripping LastProgramDeletionException (7930d92)
- build: add
make releaseandmake publishone-shot targets (091bd51) - fix(start-here): dismiss the pill on any user-driven plan change (4733e45)
- feat(program-tab): rename to "Plan" and redesign overview as soft container (defece4)
- feat(plan): always keep exactly one active plan around (94f192d)
- copy(exercises): tighten the empty-state to a single-line CTA (60458ae)
- test(drill-player): anchor sheet-closes-on-stop test to the wall clock (69fab40)
- feat(onboarding): implement four-stage first-launch flow (eb5ec77)
- feat(notifications): defer OS prompt behind in-app rationale (e4f85fe)
- docs(adr): accept ADR-0038 — four-stage first-launch onboarding (6c6a9d0)
- feat(consent): ask for analytics consent before the welcome flow (ee39c4c)
- fix(notifications): stop reporting permission-decline as init failure (b941831)
- chore(make): add
make i18nand stop claimingmake buildcovers l10n (272f3f5) - fix(about): stop spamming Sentry on harmless launchUrl false-positives (9eef517)
- fix(sentry): drop locate-me GPS timeouts from beforeSend (ff4d92a)
- chore(ios): refresh Podfile.lock after CocoaPods reinstall (dd0d11f)
- docs: add App Store review notes and TestFlight tester guide (8b70501)
- fix(map): stop reporting GPS locate timeouts to Sentry (c4ebede)
Changes since 1.0.3+22:
- feat(map): frame location picker on context when position is empty (bb053a9)
- fix: key station-row expansion by exercise+station, not local index (74e8bb6)
- feat(roleplay): inherit post position as default markør location (28b58b5)
- fix(data): persist brief markdown fields in local store (b23afd6)
- docs(onboarding): close DESIGN-007 stage 4 handoff (7a34b7b)
- test(onboarding): cover Start here show, hide, and dismissal (bd66d02)
- feat(onboarding): show Start here pill on first Øvelser FAB (c638853)
- feat(onboarding): add Start here pill widget, flag, and l10n (aedf3e2)
- docs(design): add DESIGN-007 stage 4 prompt (e05e987)
- feat(onboarding): source example plan from the real test-7x fixture (629bbd8)
- fix(map): drop "no stations created" snackbar on empty plan (5491953)
- feat(onboarding): draw example plan from the screenshot-demo content (1d14fd1)
- docs(onboarding): close DESIGN-007 stage 3 handoff (cb50b79)
- test(onboarding): cover example-open flow, locale selection, and fallback (a4b919f)
- feat(onboarding): wire Åpne et eksempel to install locale-matched example plan (1f005af)
- feat(onboarding): author and bundle localized example plan assets (437ab27)
- docs(design): add DESIGN-007 stage 3 prompt, resolve example delivery (34239d7)
- chore(store): refresh iOS App Store screenshots (c04ffae)
- fix(onboarding): center team chips on the rotation arrows (db86a8c)
- fix(onboarding): scale concept primer figure to form factor (c95d3d3)
- docs(onboarding): close DESIGN-007 stage 2 handoff (6f48d9c)
- test(onboarding): cover primer route gate, CTAs, and figure rendering (a778033)
- feat(onboarding): add concept primer route, seen flag, and CTA wiring (0d2cb39)
- feat(onboarding): add RingRotationFigure widget and primer l10n keys (6b2dbaf)
- docs(design): add notification permission priming to DESIGN-007 (76364ec)
- feat(roleplay): label markør badges with station code and number (1053eb9)
- feat(roleplay): post-scoped markør badges and required station (2128c64)
- docs(design): add DESIGN-007 stage 2 implementation prompt (ca0e230)
- fix(views): add number badges to exercise picker and station dropdown (a139ed2)
- fix(program): hide script create until exercises exist (a90a1b7)
- fix(program): disable script create without exercises (8bbb61f)
- fix(program): keep Codex's empty Teams copy (562fad9)
- test(brief): stabilize brief widget tests (69649e7)
- docs(design): keep Codex's empty Teams copy in DESIGN-007 (615895f)
- fix(player): extend mini player background through bottom safe-area inset (d084dee)
- fix(program): lead empty Teams copy with the noun, sync docs (9a74c14)
- fix(program): label plan description field as "Description" (215da6e)
- test(program): cover teaching empty states (b813e8e)
- feat(program): wire teaching empty states (24ca3e4)
- feat(program): add teaching empty state widget (4e8b827)
- feat(screenshots): add Android capture flow and platform dispatcher (cf83993)
- docs(design): detail DESIGN-007 stage 1 empty states and add prompt (7457683)
- fix(map): scale and restyle cluster count badges (f6e8279)
- docs(design): add DESIGN-007 onboarding and in-app help (0bd58d6)
- fix(plan): own dialog controllers in State to avoid use-after-dispose (e1ab6a5)
- fix(plan): dispose new-plan name controller from dialog State (0b10d4e)
- fix(brief): show role icons for unselected audiences in the audience picker (7fef6bb)
- fix(map): pre-release marker, label and fit quality fixes (d776375)
- chore(store): add iOS App Store screenshots (iPhone + iPad, en + nb) (3e48a73)
- chore(tools): shorten Norwegian demo plan title to "SOR – Øvingshelg" (2333b75)
- feat(brief): add English template variant with locale-aware resolution (cd82c91)
- fix(tools): capture screenshot from the chosen sim, not
io booted(2465929) - docs(tools): correct screenshot scaling tip to Window > Pixel Accurate (f8561a7)
- chore(tools): keep final exercise before midnight and shorten EN title (bed43a1)
- feat(tools): validate screenshot dimensions and add full --help (f94c493)
- feat(tools): dark-mode toggle, next-step hints, and full --help (f56b5c9)
- feat(tools): add dark-mode toggle and next-step hints to screenshot script (1371416)
Changes since 1.0.3+21:
- build(ios): add Shorebird release-ios/patch-ios make targets (9f047ba)
- fix(config): point catalog base URL at ringdrill.app (6929de7)
- docs(web): align iOS-release TODO with AASA wired in ADR-0021 (5386cf5)
- build(apple): migrate iOS/macOS bundle ID to app.ringdrill under DISCOOS (ADR-0021) (2138d3e)
- build(ios): bump objectVersion to 77 for CocoaPods 1.16.2 compatibility (adceddb)
- build(apple): migrate iOS/macOS bundle ID to app.ringdrill under DISCOOS (ADR-0021) (353b93f)
- fix(coordinator): darken PhaseHeaders background in light mode (915e41b)
- fix(a11y): bump PhaseHeaders cell height 24->28 to clear 1.3 text scale (a55a724)
- docs(adr): record ADR-0037 part 2 verification at cap 1.3 (c1aab48)
- fix(brief): repair 9 failing brief_screen tests (96f7abf)
- test(a11y): cover live-drill chrome at 1.3 text scale (059aedb)
- docs(prompt): add ADR-0037 part 2 a11y verification prompt (391eadb)
- refactor(exercise-form): single-row time fields + numeric-only durations (69c3ac0)
- fix(layout): stop background scaffold resizing for dialog keyboard on rail layout (5207ec5)
- docs(adr): record AlertDialog.adaptive reversal in ADR-0033 (acc2430)
- feat(team): cross-exercise team overview sheet for the Lag segment (fe351df)
- feat(map): responsive tonal map controls, search field, and zoom-button setting (d0a9501)
- Add missing import for flutter/widgets.dart (19dc4ab)
- style(reorder): nudge Ordne button padding (8e0570f)
- feat(ui): size text for legibility on iOS (ADR-0037) (2dbcdc4)
- feat(ui): use compact FAB on phones for create actions (9990718)
- docs(adr): rescope ADR-0037 to cover baseline typography, rename file (308d8e4)
- fix(program): hide new-exercise FAB in reorder mode (29741bc)
- fix(brief): keep markdown text selectable without scroll-selection crash (6c4fd4b)
- fix(program): keep Plan overview collapse stable on short lists (f0239e3)
- fix(program): keep Plan overview revealable after iOS scroll-down (9ade047)
- fix(coordinator): shorten view-selector labels to fit narrow iOS widths (7568711)
- fix(dialogs): replace AlertDialog.adaptive with AlertDialog (f0f5dbe)
- fix(sheets): bound action sheet content height to stop bottom overflow (98934c2)
- feat(brief): show a clean message when a template asset is missing (1e95be2)
- docs(adr): add ADR-0037 clamp text scaling and implementation prompt (5b7adc0)
- chore(ios): update sentry pod to 9.20.0 and refresh Flutter iOS scaffolding (80c86a6)
- fix(ios-adaptive): set status bar style on chrome-free surfaces (4e7901e)
- feat(ios-adaptive): dismiss keyboard on tap outside on forms (9ca7d81)
- docs: add iOS adaptation round 2 follow-up prompt (8588078)
- test(ios-adaptive): cover the non-iOS time picker fallthrough (cd6454e)
- feat(ios-adaptive): add haptics on toggles and drill start/stop (25a38de)
- fix(ios-adaptive): disable left-edge drawer drag on iOS (722075c)
- feat(ios-adaptive): use a Cupertino time picker on iOS (27b1bb2)
- feat(ios-adaptive): render toggles with Switch.adaptive (e0fe9c9)
- feat(ios-adaptive): render alerts with AlertDialog.adaptive (ee7276b)
- docs(adr): accept ADR-0033 and add its implementation prompt (4d37d58)
- docs(adr): accept ADR-0033 platform-adaptive UI on iOS (53fa65d)
Changes since 1.0.3+20:
- fix(exercises): show station number badge in exercise card tiles (792e8bf)
- fix(stations): restart station sub-index per exercise in Poster segment (ff5f6f7)
- feat(views): show the exercise number badge in the filter sheets (ab77cb9)
- fix(views): preserve exercise index when editing (657d6e9)
- fix(views): hide order header and add top padding when stations span exercises (f3684f4)
- fix(views): prevent station reorder snap-back after pressing Done (53814b2)
- test(views): cover the shared reorder section and station reordering (f71938a)
- feat(views): add the station badge and gated reorder to the coordinator (1984b26)
- feat(views): reorder stations in the Stations segment (48cc9d8)
- feat(services): reorder stations and remap dependent references (8f5db73)
- refactor(views): extract ReorderableSection from the exercises list (ebf7541)
- fix(map): constrain camera zoom to the tile layer's range (ada0637)
- fix(map): share one HTTP client across Kartverket tile layers (40039fa)
- docs(prompts): add ADR-0036 implementation prompt (6cc0457)
- docs(adr): add ADR-0036 and use English names in ADR prose (372f6d0)
- fix(views): defer exercise reorder commit to Done (c2eeafd)
- feat(views): lay out exercise order header per ADR-0035 alternative C (8670de3)
- fix(views): right-align list-header controls and polish visual spacing (7ed7a56)
- refactor(views): move sort/reorder controls into an in-list header (cd7ddb7)
- docs(adr): move ADR-0035 ordering controls into a list header (4add5ca)
- refactor(views): replace per-row overflow with Sorter/Ferdig reorder mode (c722a42)
- docs(adr): switch ADR-0035 reorder UX to a dedicated reorder mode (a34f42d)
- chore(data): rename sort lambdas so rg check for old exercise name sort passes (323eac6)
- test(views): cover exercise reordering and renumbering (f892b91)
- feat(views): add move up/down and one-shot sort actions for exercises (765d917)
- feat(views): drag to reorder exercises in the Øvelser segment (7e39fa1)
- feat(services): assign exercise index on create/copy/import and add reorder (85efc83)
- feat(data): order exercises by index with deterministic legacy migration (81cc454)
- feat(models): add index field to Exercise for explicit ordering (a50870d)
- docs(prompts): add ADR-0035 implementation prompt (f44aa23)
- docs(adr): add ADR-0035 for explicit exercise ordering (ba3b2e9)
- fix(tests): update widget tests to renamed badge API (fe532aa)
- feat(views): add the station number format picker to the plan form (c7e10ff)
- refactor(brief): drive station codes through Numbering and honour the plan format (d0dbbe2)
- feat(views): show the exercise number badge in exercise list rows (4ab3eda)
- refactor(views): rename badge family to *NumberBadge and make them format-agnostic (405a192)
- feat(models): add per-plan number format fields to Program (16c3d4a)
- feat(models): add Numbering module with exercise and station formats (5fb423f)
- docs(prompts): add ADR-0034 implementation prompt (c3614aa)
- docs(adr): add ADR-0034 for centralised, per-plan numbering formats (cce0491)
- fix: increase copy button padding in coordinator plan view (4f01cfe)
- fix(drill-mini-player): prevent tiles from rendering behind play button in idle state (d8150ee)
- feat(map): highlight live stations and clusters during a running exercise (767cf0e)
- docs(adr): add ADR-0033 for selective platform-adaptive UI on iOS (6042f97)
- docs(release): add Google Play release notes for 1.0.3+20 (20c7f35)
Changes since 1.0.3+19:
- fix(views): pad roleplay edit action and open plan form from title (82db6e6)
- test(forms): cover OptionalFieldSections + brief-field round-trips (4db92bf)
- feat(station): addable brief sections on StationFormScreen (0b55c1f)
- feat(exercise): addable brief sections on ExerciseFormScreen (8d8289e)
- feat(program): add ProgramFormScreen and wire it from the overview (c40f5fc)
- refactor(widget): extract OptionalFieldSections from RolePlayFormScreen (6f3f8d6)
- docs(prompt): add addable-field forms prompt (item 13) (d7a3acc)
- fix(roster): refresh actor subtitle on cast / uncast (6a083b1)
- refactor(roleplay): retire cast-roster action from Spill segment (e17f989)
- feat(l10n): rename Spill segment create FAB to "Nytt spill" (e8a9e4c)
- fix(widget): stop PhaseTile overflowing at narrow widths (159ccff)
- fix(widget): clip PlanStatusBadge InkWell to badge bounds (e517d9b)
- docs(prompt): add DESIGN-006 polish-batch prompt (7fb664b)
- docs(design): amend DESIGN-004 editing model to addable fields (5048eb4)
- docs(prompt): note PlanStatusBadge InkWell follow-up (241404a)
- docs(prompt): update DESIGN-006 follow-up tracking (9814653)
- test(roster) + docs(design): cover the Roster tab and close stage 4 (42139e2)
- feat(navigation): add the Roster destination and route (49bec16)
- feat(roster): RosterView and RosterController (c548583)
- docs(prompt): add DESIGN-006 stage 4 (Roster tab) prompt (0d43274)
- docs(prompt): close out script-segment rename, park SilentWitness (556e5ba)
- docs(design): rename Markører segment to Spill in DESIGN-006 (84fa443)
- feat(l10n): add scriptSegment key (en "Script", nb "Spill") (610d8e9)
- refactor(program): rename ProgramSegment.roleplays → script (eb0241e)
- docs(prompt): add Spill/Script segment rename prompt (ab0d69f)
- fix(program): unify segment actions, filters and the create FAB (b79ab32)
- fix(program): reveal overview on segment switch (87b4d25)
- feat(program): replace overview summary line with a show-more toggle (cd2a97d)
- fix(program): rework Program overview to a manual collapse (df23b8e)
- fix(program): force switcher sliver to fill declared extent (ffd9dcc)
- docs(prompt): DESIGN-006 stage-3 off-scope findings (d462563)
- test(program): cover the overview (ae035e5)
- docs: correct DESIGN-006 stage 3 brief-field and scroll assumptions (ba46365)
- feat(program): wire Åpne brief and retire per-segment brief action (e1bfb8b)
- feat(program): collapsing overview and pinned switcher (59b4cfe)
- docs(prompt): add DESIGN-006 stage 3 implementation prompt (1ed7a5c)
- docs(prompt): DESIGN-006 follow-ups handoff (3c06088)
- feat(settings): staff-only app-user role, driving the brief default (410c022)
- feat(roleplay): add 'Ny rolle' FAB to Markører segment (77a8259)
- fix(widget): set heroTag: null on filter FABs (1591bd1)
- docs(prompt): add DESIGN-006 follow-ups implementation prompt (0a4d2ec)
- fix(navigation): defer program activation out of the GoRouter redirect (9a4aaab)
- test(navigation): cover program-scoped routing (13c0661)
- feat(navigation): collapse structural root tabs (d926e44)
- feat(navigation): redirect legacy program routes (52cd162)
- feat(navigation): add program-scoped route tree (ac4a110)
- docs(prompt): add DESIGN-006 stage 2 prompt and reconcile stage list (a4161b0)
- style(navigation): tidy AppBar titles, subtitle and action order (5ba45c3)
- fix(program): show label-only segments and dispose RolePlaysController (802e167)
- test(program): cover segmented program tab (b1f1a62)
- feat(program): delegate contextual segment chrome (107f061)
- feat(program): embed structural segment bodies (a2e3d5d)
- feat(program): add segmented program switcher (3712cff)
- docs(prompt): add DESIGN-006 stage 1 implementation prompt (ff169d0)
- feat(catalog): surface unpublished changes in plan badge with one-tap publish (7cdcdba)
- fix(catalog): preserve local actors when overwriting from catalog (82bc215)
- docs(design): record delivery strategy and ADR-0028 ordering in DESIGN-006 (26f26d1)
Changes since 1.0.3+18:
- fix(team): match live exercise by uuid in TeamExerciseScreen (ff13c17)
- docs(adr): add ADR-0032 program-scoped routing (1c5bc6b)
- docs(design): add DESIGN-006 program tab consolidation, supersede 002/003 (35350ec)
- feat(coordinator): add all-stations map segment to mobile body (2d50f1e)
- feat(map): hide app bar on Map tab in compact layout (7cf1c2e)
- fix(coordinator): center round table + status tile and pin status background (9f05c90)
- feat(program): move new-exercise FAB to extended label in master pane (346379a)
- feat(coordinator): replace status bar + FAB with a docked tile mini-player (56ce8ac)
- fix(coordinator): show view selector in wide layout, anchored to list column (c3345bf)
- feat(program): expand stations inline in ExerciseCard + extract ExerciseMiniMap (87c6f3a)
- feat(program): inline station list in ExerciseCard with edit + open gestures (8795b07)
- fix(program): open exercise edit form on long-press (ba7f950)
- refactor(program): align exercise card swipe chrome with ADR-0031 reference pattern (a1f7f91)
- docs(row-edit-affordances): tighten ADR-0031 and extend prompt with program_view alignment (153b7b7)
- refactor(widgets): centralize ExpandableTile long-press handling (019fa7a)
- feat(rows): add long-press editing to stations and roleplays (235a39f)
- feat(coordinator): long-press edit team rows (5eaa1f6)
- feat(coordinator): swipe-to-edit station rows in exercise overview (0d395d9)
- feat(teams): edit team via swipe, long-press, and detail-sheet action (e603ddf)
- feat(team): add TeamFormScreen for editing team name, members, position (c3c1b88)
- feat(program-service): public saveTeam wrapper + teamSaved event (f4301a7)
- docs(prompts): add DEBT-0005 context-extension sweep prompt (cb49b95)
- docs(prompts): add DEBT-0005 context-extension sweep prompt (3bedd73)
- docs(debts): update DEBT-0002/0004/0005/0006 statuses (b48b4df)
- refactor: migrate coordinator lists to ExpandableTile + LiveAccent (DEBT-0002) (acacad7)
- refactor: add SubscriptionBag mixin and adopt in main/stations (DEBT-0006) (2108ac0)
- refactor: extract shared destructive-confirm dialog (DEBT-0004) (8c86914)
- refactor: add BuildContext extension for l10n/colors/texts (DEBT-0005) (497e530)
- docs(prompts): add coordinator-consolidation debt paydown prompt (6a78faf)
- fix(shell): clear detail pane when exercise starts in master/detail (3f70c4c)
- fix(wide): make master cards pop in dark wide layout (87039fb)
- fix(wide): rework mini player placement and narrow-mode fallback (df811a7)
- fix: remove dead expression in generateSchedule and correct test docs (b4df8e5)
- docs(debts): record nine tech-debt entries from codebase review (dc6d09c)
- feat(wide): unified visual hierarchy across master/detail panes (f238661)
- fix(shell): make NavigationRail span full height in narrow medium layout (4e45d1e)
- docs(prompts): add ADR-0021 implementation prompt (cfecf4b)
Changes since 1.0.3+17:
- Improve cast picker actor management (1832a82)
Changes since 1.0.2+16:
- docs: document release-tag workflow in README and AGENTS (f03a227)
- build(make): add release-tag target (80e0e74)
- fix(wide): multiple master-detail UX fixes (e3bdd35)
- feat(wide): open fullscreen coordinator from mini player (fc4c5b3)
- feat(wide): merge idle play bar into DrillMiniPlayer (e27837f)
- fix(wide): close() always clears active scope regardless of _isOpen state (d13cc91)
- fix(wide): close button clears master-detail target instead of nav pop (0cd4061)
- fix(wide): keep exercise target alive when exercise starts/stops (00fc578)
- feat(wide): move play control to master column in wide layout (6aab6ad)
- feat(wide): highlight selected master-list item and widen master column (5f91631)
- fix(player): close drill sheet when exercise stops (d77bde7)
- fix(coordinator): anchor play button in top section (1aafe18)
- fix(coordinator): account for wide row height in map sizing (1c1ebae)
- fix(coordinator): preserve bottom gutter around wide map (f125c62)
- fix(coordinator): expand wide map to viewport height (1737d05)
- fix(sentry): ignore disposed Flutter web view noise (1d0dbab)
- fix(coordinator): trigger wide layout inside detail pane (e9797fd)
- feat(coordinator): add wide two-column overview (3cd401e)
- fix(shell): guard map split below minimum width (f3cf667)
- fix(shell): scope master list taps to detail pane (fe3ac54)
- fix(forms): address ADR-0030 verification issues (2f64676)
- Add new RingDrill v2 design files and generated assets (e997d34)
- refactor(forms): migrate form call sites to openFormSurface (d1ab1d1)
- refactor(shell): split Map tab into map and detail panes (c725afd)
- refactor(shell): mount master/detail in MainScreen with mini-player anchored to master footer (bc715ed)
- feat(shell): empty-pane widgets per list tab and l10n (ca5e7ce)
- feat(context-sheet): short-circuit show through MasterDetailScope (228d7e2)
- feat(sheet): add showRingdrillFormDialog and openFormSurface (3f7ab2d)
- feat(shell): add WindowSizeClass and MasterDetailScope infrastructure (04c5c1f)
- docs(prompts): add ADR-0030 implementation prompt (5ec4d32)
- docs: add ADR-0030 and DESIGN-005 for wide-screen master/detail layout (e0aea5d)
- test: align brief/station/share tests with current implementations (445b0bf)
- fix(brief): let context sheet expand to full width for brief target (6f37abf)
- docs(adrs): add ADR-0029 — live mini player surface (925cea7)
- Add regression tests for ProgramService catalog refresh logic (8f54ab1)
- fix(catalog): detect local-only edits when refreshing from catalog (9b7f8e8)
- feat(exercise): auto-stop on endTime expiry with snackbar + notification (a5dde67)
- fix(views): drop done events so stopped exercises lose live styling (5ae2abf)
- feat(player): add mini-bar stop button, fix full-width progress strip (45b62b5)
- feat(player): scroll mini-bar round-row behind right cluster, hour-format long countdowns (dbedda9)
- refactor(player): mirror PhaseTile structure in MiniRoundRow, add fontSize to PhasesWidget (d196598)
- fix(service): use elapsed minutes for _totalProgress (770e3bb)
- test: fix two pre-existing failing tests (b7c949d)
- docs(player): append followup-03 steps to handoff log (b5c09d8)
- feat(player): animate mini-bar play icon (pulse pending, spin running) (fef227a)
- fix(player): bottom mini-bar strip tracks total exercise progress (fb34bd1)
- fix(player-sheet): drop chevron, square corners, fill viewport height (9a9e375)
- refactor(widget): reuse PhasesWidget in MiniRoundRow so completed phases stay filled (8c3a144)
- refactor(widget): split R1/N into R1 + appended {N} runder cell in MiniRoundRow (2e58f5e)
- feat(player): brighten the mini-bar progress strip (fab30ed)
- feat(player): restore phase label before mini-bar countdown (89e999c)
- refactor(player): enlarge non-badge text in DrillMiniPlayer and MiniRoundRow (22d9aef)
- feat(widget): make ExerciseNumberBadge size configurable for the mini-bar (343af2a)
- feat(player): show mm:ss countdown in mini-bar pending state (0477bbd)
- docs(player): add V1 follow-up 03 (mini-bar polish, sheet cleanup, animated play ring) (719c25c)
- docs(player): append followup-02 steps to handoff log (6d657e0)
- test(player): cover new mini-bar layout and helper widgets (3377d77)
- feat(navigation): float DrillMiniPlayer with rounded corners above the navbar (28960ed)
- refactor(player): rebuild mini-bar layout around ExerciseNumberBadge and MiniRoundRow (958d373)
- feat(widget): add MiniRoundRow for the DrillPlayer mini-bar (82cfcb0)
- feat(widget): add ExerciseNumberBadge sibling to StationCodeBadge (9f78397)
- docs(player): append followup-01 steps to handoff log (96ca8c7)
- test(player): move sheet test next to mini-player test for consistency (86f2bf1)
- feat(player): tint mini-bar with LiveAccent background (6c3c075)
- refactor(player): place mini-bar progress strip below the row, Spotify-style (4a0d569)
- feat(player): tick mini-bar per second for smooth mm:ss countdown (f68cf16)
- feat(navigation): auto-close exercise ContextSheet when it goes live (5c17d6d)
- docs(player): add V1 follow-up 02 (mini-bar redesign) (c6ca3a2)
- docs(player): add DESIGN-001 V1 follow-up 01 (mini-bar polish) (758eb84)
- fix(test): add missing ExerciseSheetTarget case in context_sheet_test (d769217)
- docs(player): add DESIGN-001 V1 handoff log (468a9c1)
- test(player): cover DrillMiniPlayer and DrillPlayer sheet behaviour (2370037)
- feat(program): open DrillPlayer for live exercise card (4a4fc10)
- feat(navigation): mount DrillMiniPlayer above bottom nav (37846ac)
- feat(player): add tap-only DrillMiniPlayer widget (45da5bf)
- feat(player): add immersive DrillPlayer sheet shell (4d5b98b)
- docs(player): add DESIGN-001 V1 implementation prompt (83cac0a)
- docs(design-001): lock V1 scope for Exercise Player (56fc0e5)
- docs(adrs): add ADR-0028 grouping lib/views/ by feature (adac200)
- feat(map): replace OSM base layer with Kartverket grayscale topo (dcc2395)
- fix(stations-filter): restore exercise show/hide-all and drop duplicate Vis alle (1fc1468)
- refactor(nav): open coordinator screen as a sheet target (edf093d)
- fix(sheet): show entity identity in viewer-sheet header, drop body duplicate (96a4b9e)
- fix(sheet): tint station mini-map sheet header with AppBar theme (63fa5fb)
- refactor(sheet): collapse viewer header into body AppBar (a4422ee)
- docs(prompts): add follow-up 01 collapsing the viewer-sheet header (89a5a1d)
- docs(adrs): revise ADR-0027 to drop viewer-sheet header row (cbae8fb)
- fix(sheet): give fill-style action sheets finite height (672b537)
- fix(sheet): provide ContextSheet scope for coordinator routes (1b01876)
- Update ringdrill-v2.xcf image asset (108dd86)
- refactor(sheet): drop sidebar tint from brief TOC sheet (0531e35)
- refactor(sheet): migrate all action sheets to showRingdrillActionSheet (0d292c4)
- refactor(sheet): route ContextSheet host through showRingdrillViewerSheet (c8f8205)
- feat(sheet): add showRingdrillSheet helper with viewer and action variants (12be683)
- docs(prompts): add implementation prompt for ADR-0027 (4e624a8)
- docs(adrs): add ADR-0027 unified bottom sheet chrome (50dad3e)
- fix(nav): allow root routes to open ContextSheet (63d76d7)
- feat(brief): append viewer link to copied brief markdown (115abac)
- refactor(nav): keep deep links opening the right sheet on the right tab (23abea8)
- refactor(nav): route station, team and role taps through ContextSheet (635fcde)
- feat(nav): mount ContextSheet in MainScreen and fold in BriefSheetLauncher (fc9698b)
- Add trailing icons to external link list items (5019cdc)
- feat(nav): add ContextSheet controller and sealed sheet targets (ec0a47b)
- docs(prompts): add implementation prompt for ADR-0026 (bc950f7)
- feat(stations): tint station code badge when roleplayers are attached (2e226e3)
- feat(build): bake git commit into release builds (44ad765)
- docs(adrs): add ADR-0026 sheet-based context navigation (6650a75)
- feat(coordinator): tap team-round card to open station (4ccf2e3)
- feat(coordinator): declutter appbar and tune disabled icon contrast (b830c0e)
- feat(theme): extract to lib/theme.dart and apply v2 icon palette (3d8ed63)
- design(icon): Changed background splash color (c35f073)
- design(icon): Redesigned ringdrill icon (853b9c2)
- refactor(brief): move floating TOC button to bottom-right corner (43dc81f)
- fix(brief): drop program H1 from sidebar and narrow TOC outline (2ceeffa)
- feat(brief): no-position label, floating actions and compact audience picker (3158b83)
- fix(brief): handle in-doc anchor links without reloading the page (b75d923)
- fix(brief): handle in-doc anchor links without reloading the page (c34dae9)
- fix(brief): land on program route when closing deep-linked brief sheet (e5328ae)
- docs(brief): add follow-up prompt for cross-platform PDF export pivot (fb97335)
- feat(brief): cycle through search matches with highlights and auto-scroll (ce9e5ce)
- feat(brief): wide-screen polish — dynamic title, full-width sheet, compact TOC and inline rotation legend (6d3f24e)
- feat(brief): omit program-level intro in single-exercise mode (4830782)
- feat(brief): copy inline code to clipboard on tap with snackbar feedback (78eda8e)
- Update Norwegian localization for rotation legend (a03e6bc)
- style(brief): bump inline-code chip background contrast for visibility (797882e)
- fix(brief): render inline code as padded chip via custom SpanNode (95eb559)
- revert(brief): restore tight heading line-heights (321f5c1)
- feat(brief): add breathing room between sections and inline-code UTM (ed0c950)
- docs(brief): amend ADR-0023 revisions and update DESIGN-004 fields (5b1464c)
- feat(brief): rewrite nb template, restore Varighet heading, filter TOC to H2+H3 (98d8d8d)
- feat(brief): split duration helpers and add exercise-time and organisation helpers (b610e44)
- refactor(utils): extract rotation-block formatter shared by brief and share (86c78ed)
- feat(data): add Program.beforeRoundMd markdown file field (33e62ce)
- docs(brief): add ADR-0023 follow-up prompt for template content polish (39d38fe)
- fix(brief): escape | in setupLabel and use
for in-table line break (fbff101) - feat(brief): present brief as fullscreen modal bottom sheet from /brief route (b3c4f2e)
- refactor(brief): adopt BriefTheme and BriefMarkdown in BriefScreen with slim app bar (624eacc)
- feat(brief): gate in-doc TOC and demote one-line headings in nb template (366fe07)
- feat(brief): add BriefMarkdown wrapper composing BriefTheme into markdown_widget (2b72be0)
- feat(brief): add BriefTheme tokens with light and dark factories (971707e)
- docs(brief): add implementation prompt for ADR-0023 (d9db9cf)
- docs(brief): add ADR-0023 BriefTheme tokens and update DESIGN-004 (c2d679b)
- test(views): cover BriefScreen audience toggle and template asset loading (41f0695)
- feat(views): add Brief action to CoordinatorScreen and ProgramView app bars (1ae7018)
- feat(views): add /brief routes and BriefScreen (f1bf411)
- feat(l10n): add brief screen and audience-toggle strings (e4289c0)
- chore(deps): add markdown_widget for brief viewer (6f0e12e)
- docs(prompts): add Stage 3 implementation prompt for DESIGN-004 (6a61a0b)
- test(services): cover BriefRenderer for participant/instructor/director audiences (c737d19)
- feat(services): add BriefRenderer with helpers and audience gating (bdd2af2)
- feat(assets): add ringdrill-standard-v1 brief template (nb) (d54f60c)
- feat(services): scaffold BriefAudience, Template and TemplateRegistry (212324a)
- chore(deps): add mustache_template for brief rendering (663358e)
- docs(design): clarify BriefAudience axis vs. session-runtime roles (80b4f96)
- feat(views): replace slide-to-delete with slide-to-edit on exercise list (aa5c709)
- test(data): cover Stage 1b field roundtrip and content-hash stability (b61f6d4)
- feat(data): fold Stage 1b markdown fields into ProgramX.computeContentHash (b488e87)
- feat(data): read/write Stage 1b markdown fields as .md files in DrillFile (5b40380)
- feat(models): add brief markdown fields on Program, Exercise, Station, RolePlay (86a29a6)
- feat(models): add templateId on Exercise and variantSuffix on Station (0b7a746)
- docs(prompts): add Stage 1b implementation prompt for DESIGN-004 (44430f5)
- feat(views): apply card design language to RolePlayScreen and RolePlays expandable tile (369a921)
- refactor(roleplay-form): move position field between station and optional sections (a89e9a3)
- refactor(views): put name and age on the same row in RolePlayFormScreen (80c2f58)
- feat(views): add × button to remove optional sections; drop AppBar subtitle (0e1cee6)
- feat(views): hide empty sections in RolePlay views; add section support in form (a26bf93)
- refactor(views): navigate to RolePlayScreen via GoRouter context.push (331334b)
- feat(views): static AppBar title on RolePlayScreen, remove section header (d74caef)
- feat(data): bump drillSchemaCurrent to 1.2 and fold markdown into computeContentHash (f12f3d0)
- test(data): cover 1.1-to-1.2 migration of behavior, background and actor notes (d69be59)
- feat(data): read/write markdown fields as .md files in DrillFile with legacy-inline fallback (946d74d)
- feat(models): annotate RolePlay.behavior/background and Actor.notes with @JsonKey(include*=false) (0efe3fe)
- feat(data): add drillSchema1_2 constant and accept 1.2 server-side (1a902ba)
- docs: add ADR-0022 Stage 1a implementation prompt (2e7111a)
- docs: accept DESIGN-004 brief template and ADR-0022 markdown-as-files (991d66d)
- ci(web): wait for Netlify CDN to propagate before Lighthouse audit (2a2d27c)
- ci(deps): bump actions/cache from 4 to 5 (41db612)
- ci(web): drop the flaky DIY smoke test (dbc5ebf)
- fix(smoke): make smoke checks renderer-agnostic (skwasm-safe) (eaa3b97)
- fix(smoke): give WASM enough time to paint, survive page-close errors (6a5cd26)
- chore(deps): regenerate package-lock.json for puppeteer (f933a8f)
- Add link and badge for the RingDrill web version (0e48184)
- build(web): switch web build to dart2wasm, keep dart2js as fallback (297775a)
- chore(web): act on Lighthouse a11y and SEO findings (5ea745a)
- ci(web): add post-deploy smoke test that paints actually happen (a7ddd25)
- fix(main): expand Stack so the IndexedStack does not collapse to 0x0 (d2b4eea)
- ci(web): keep Lighthouse, move it from Netlify plugin to GH Actions (7f450e7)
- ci(web): replace actions-netlify with first-party netlify-cli (dd74c50)
- fix(ci): tell actions-netlify where the functions live (97f8571)
- ci(web): scope deploy job to PROD environment (60fce45)
- fix(map): hide locate-me "Settings" action on web (9a5048e)
- chore(sentry): drop debug-build events before they ship (44827a7)
- chore(sentry): drop WebExtensions messaging noise (70f5f56)
- fix(service): ensure active program before saveActor/saveRolePlay (ad94c28)
- ci(deps): bump actions/checkout from 4 to 6 (d767ef5)
- ci(deps): bump actions/setup-node from 4 to 6 (b8a81c9)
- ci(deps): bump subosito/flutter-action in the actions-minor-patch group (2e1f2e3)
- chore(sentry): drop "Script error." and other un-actionable noise (69d7da2)
- ci(deps): set up Dependabot for actions, pub and npm (edc1c02)
- ci(web): pin subosito/flutter-action to v2.21.0 (3ab4125)
- build(web): move release pipeline to GH Actions, upload maps to Sentry (84ace28)
- fix(router): mount ShellRoute child + stub tab builders (35e124a)
- fix(router): mount ShellRoute child so Android back stops crashing (3cc23d2)
- fix(drill): replace late-final locals with explicit FormatException (cbe8462)
- fix(boot): keep main() reaching runApp() so the web splash never hangs (73743e3)
- docs(adrs): accept ADR-0021 on Apple bundle-ID split under DISCOOS team (246eb4d)
- fix(web): add source-maps to build (882eafe)
- fix(map): reject non-finite LatLng at every boundary (208aabb)
- docs(prompts): split roleplay marker routing into ADR-0020 follow-up 04 (b7ee52b)
- refactor(map): add per-layer zoom bounds to MapConfig tile layers (46edf27)
- docs(prompts): add ADR-0020 follow-up 03 for per-layer zoom bounds (4c2590f)
- refactor(map): unify marker cluster group and drop refit on filter changes (15af88c)
- docs(prompts): merge ADR-0020 follow-ups 02 and 03 (04c393b)
- refactor(map): consolidate three filter FABs into one unified filter sheet (c80e4d8)
- docs(prompts): add ADR-0020 follow-up 01 for unified filter command (1dff603)
- feat(map): reduce marker clutter via clustering, zoom-gated labels and visibility toggles (dfd553f)
- docs(prompts): add ADR-0020 implementation prompt (2bb10d5)
- docs(adrs): accept ADR-0020 on map clutter + unified marker spec (46d7d46)
- Unify expandable cards and surface live exercise across all tabs (e575703)
- chore(design): Refactor marker labels into reusable widget (10d75f6)
- fix(design): Refactor coordinator screen UI and add live team styling. (aa486e2)