Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changes/flow-colour-views.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "type": "user-facing", "releaseNoteId": "release:0.20.0" }
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ All notable Loop Studio releases, newest first. Behavioral changes are pinned
in versioned spec documents (see the [README](README.md#technical-reference));
this file is the narrative history, not the contract.

## v0.20.0 — 2026-10-07

Flow colours beyond the canvas (issue #325, the second of three parts). The contract is [`docs/flow-colour-and-compact-nodes.md`](docs/flow-colour-and-compact-nodes.md) FC-5 and FC-6.

- **The minimap and the timeline.** A coloured node's minimap mark takes its colour, and a coloured Pool or Register draws its timeline line, its legend mark and its endpoint in it. Every other mark and series keeps its colour, so colouring one node never recolours another; the Register's dashed line and the Pool's solid line stay, and connection colours never reach the timeline. Under forced colours neither view draws a flow colour.
- **Three templates in colour.** The Coffee roastery, gacha banner and early MMO templates open with three colours on their main flows: green beans, roasted beans and desserts; the gacha banner's three zones, in the colours their frames already carry; items, gold and experience. Parameters and Registers stay uncoloured. Their simulation is unchanged: the engine digest of each template is the one recorded before.
- **Each colour once.** In the Inspector's Colour section, Recent leaves out the palette's colours, and In this document leaves out both, so the current colour's ring shows once; a row with nothing left is hidden.
- **The phone shows a colour as one line.** The read-only Inspector on a phone shows the colour as text, a dot with the colour's name and hex (its hex alone off the palette), Default with an empty ring, Mixed with no dot, instead of the disabled editor. A locked canvas on the desktop keeps the disabled editor.

**No migration.** Run results and the run CSV are unchanged for any diagram. The three templates' files now carry `accent` fields, so their content and revision digests differ from v0.19.0's. Four release-note lines in 18 languages, 16 of them without native review. The informational `meta.tool` string is now `loop-studio/0.20.0`.

## v0.19.0 — 2026-10-06

Flow colours (issue #325, the first of three parts): nodes and connections can carry a colour so the flows of a large graph read apart at a glance. The contract is [`docs/flow-colour-and-compact-nodes.md`](docs/flow-colour-and-compact-nodes.md).
Expand Down
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,19 @@ Additional feature-specific design documents (localization, mobile, module
system, large-graph readability, simulation playback, edge routing, data
import, …) live under [`docs/`](docs/).

## Latest — v0.19.0
## Latest — v0.20.0

Flow colours beyond the canvas.

- **The minimap and the timeline** show a coloured node in its colour; a coloured Pool or
Register draws its timeline line in it, and every other series keeps its own
- **Three templates in colour**: Coffee roastery, the gacha banner and early MMO open with
three colours on their main flows; their results are unchanged
- **Each colour once** in the Inspector: Recent and In this document leave out the colours
already shown above them
- **On a phone**, the read-only Inspector shows a colour as one line: a dot, its name and hex

## v0.19.0

Flow colours: give nodes and connections a colour so a large graph's flows read apart.

Expand Down Expand Up @@ -173,18 +185,8 @@ A fix release: the menus answer the keyboard the same way.
- **On a phone**, a sheet takes focus when it opens, and Escape in a sheet opened from
More goes back to More; the run bar and the update bar stay usable

## v0.18.0

The third-party open-source licenses, inside the app.

- **About Loop Studio → Third-party open-source licenses** shows the full license text of
every third-party component the build includes, in its original English, in the same
dialog; Back returns to About
- **Offline too**: the installed app has the text precached, and the single-file version
carries it inside the file; the web and installed builds also open it as a text file
- **Loop Studio's own notice is unchanged**: the licenses cover the included components only

See [`CHANGELOG.md`](CHANGELOG.md) for the full notes of these releases, v0.17.2 (the
See [`CHANGELOG.md`](CHANGELOG.md) for the full notes of these releases, v0.18.0 (the
third-party open-source licenses in the About dialog), v0.17.2 (the
Temporary session button drawn like the menu buttons), v0.17.1 (share
links compressed with the browser's own Compression Streams), v0.17.0
(password-protected share links), v0.16.0 (the storage gate, temporary sessions and the
Expand Down
Binary file modified docs/assets/coffee-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/gacha-overview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/gacha-pickup-guarantee.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/hero-coffee.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assets/mmo-focus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 18 additions & 5 deletions docs/flow-colour-and-compact-nodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,23 @@ The flow colour is a rest colour. Every state that restyles an element today sti
- The browser's colour input applies on its real `change` event only: never on opening it and never on the live `input` events while its dialog is open, so opening it on Default or on a mixed selection applies nothing (in particular, never black).
- Each swatch is a `<button>` with the colour's name (or its hex for recent and document colours) and `aria-pressed`, plus a visible pressed ring that survives forced colours. Everything works with the keyboard alone.
- Notices (FC-3.3) sit under the controls, in a polite live region.
- Phone: the Inspector is a read-only sheet there (`docs/mobile.md` MV-D3), inside `<fieldset disabled>`, so the section shows the current colour and every control in it is disabled. A locked desktop canvas disables it the same way. A colour set anywhere renders everywhere.
- Each colour is offered once (PR 2): Recent leaves out the palette's colours, and In this document leaves out the palette's and Recent's, so the current colour's ring shows once. A row left empty is not shown.
- Phone: the Inspector is a read-only sheet there (`docs/mobile.md` MV-D3), and the section is one line of read-only text, with no control (PR 2): a dot and the colour's name and hex for a palette colour (`Rose #B47599`), the dot and the hex alone for any other, **Default** with an empty ring, **Mixed** with no dot, since a dot would read as one particular colour. The hex is a `dir="ltr"` run. A locked desktop canvas keeps the editor inside `<fieldset disabled>`: every control disabled, the hex field and the colour input drawn with the disabled ink and boundary of the other read-only fields and no pointer cursor, the swatches still showing the current colour and its ring. A colour set anywhere renders everywhere.

## FC-6. Minimap, timeline and templates (PR 2)

- The minimap mark of a node with a flow colour takes it; others keep the kind hue.
- A Pool or Register series in the timeline takes its node's flow colour; others keep the current series colour. Edge colours are not passed to the timeline. The Register dashed line and the Pool solid line stay. CSV export and simulation data are unaffected.
- Templates get restrained colours (about three per screen) on their main flows; their simulation results do not change.
- The minimap mark of a node with a flow colour takes it; others keep the kind hue (`MinimapDock`).
- A Pool or Register series in the timeline takes its node's flow colour, for its line, its legend mark, its endpoint dot and label; others keep their colour by index, so colouring one node never recolours another series (`TimelineChart`). Edge colours are not passed to the timeline. The Register dashed line and the Pool solid line stay. CSV export and simulation data are unaffected.
- Under forced colours neither view draws a flow colour (FC-3.4). Both paint inline SVG `fill` / `stroke`, which the system palette does not replace, so they ask `useForcedColors()` (`src/ui/media.ts`) and fall back to the colours they draw today.
- Templates get restrained colours, three each, on their main flows; their simulation results do not change. The colours are data in the shipped file, written by the Template's builder through `withTemplateFlowColours` (`src/engine/templateFlowColours.ts`): each listed node takes its flow's palette colour, and so does every resource edge whose two ends are in the same flow; a Parameter, a Register, a missing id or a node listed twice fails the build.

| Template | Sage | Gold | Violet | Rose |
|---|---|---|---|---|
| Coffee roastery operations flow | green beans | roasted beans, from the roast on | — | desserts |
| 3-zone gacha banner comparison | General / Free zone | — | Premium Standard zone | Premium Pickup zone |
| Early MMO progression | items and loot | gold | experience and level | — |

The gacha zones take the colour their frames already carry. Uncoloured: every Parameter and Register, the gacha comparison row, the MMO combat chain, encounters and upkeep. Each Template's engine digest equals the one recorded before the colours; its content and full revision digests change with them.

## FC-7. Compact nodes (PR 3)

Expand All @@ -211,13 +221,16 @@ Unit:
- `src/model/flowColour.test.ts` — `serialize` → `deserialize` keeps `accent` on all eight node kinds and both edge kinds, and a file without it gains nothing; an invalid value is dropped and the element kept; a module insert keeps every colour; selection flags never reach the file; `semanticDigest` is unchanged by setting, changing and removing colours and by selection flags; the full revision digest changes and comes back; equal colours in either case give equal digests; a document with no colour projects byte-identically and the `/1` projection never emits it; a side with a surviving colour is `loop-revision/9` and its stored digest verifies; `fieldTag` is `cosmetic`; a colour-only diff is neither engine- nor advisory-affecting; a selective Apply adds, changes and removes it.
- `src/store/graphStore.accent.test.ts` — `setAccent` over several nodes and edges is one undo entry; undo and redo restore each element's colour or its absence and never move `simulationRev`; re-applying is no entry; an invalid value changes nothing; `updateNodeData` / `setEdgeData` with only `accent` move no `simulationRev`, a real change still does; `accentTargets` follows the `selected` flags, else the Inspector's element.
- `src/store/recentAccents.test.ts` — at most 8, newest first, de-duplicated, stored form only; memory only in a temporary session; removed by the reset.
- `src/engine/templateFlowColours.test.ts` (PR 2) — `withTemplateFlowColours` colours the listed nodes and the resource edges inside one flow and fails closed; each Template carries exactly its builder's colours, never on a Parameter or a Register, an edge coloured exactly when it is a resource edge inside one flow; its engine digest is the one recorded before the colours (`sha256Baseline.fixture.ts`), and its content and full revision digests are pinned at their values with the colours. `src/model/sha256Baseline.test.ts` keeps the recorded #301 digests: for these three files it checks the engine digest as recorded, and an explicit legacy test removes `accent` and checks all three recorded digests.
- `src/ui/flowColour.test.ts` — every palette colour gives no notice and passes 3:1 on the four surfaces; the measured faint colours give the right notice for the right place and theme; the state-colour notice; the DOM id fragment.

End to end (Chrome; desktop, the `mobile` project, forced colours, both themes):

- `e2e/flow-colour.spec.ts` — a palette colour and Default on a node; an edge's line, its own arrow (one marker per colour, no `#` in an id) and its label; one choice over a multi-selection as one undo step, and Mixed; the browser colour input applying on `change` only, also on a mixed selection; the hex field, its refused alpha, its notices and Escape; keyboard only; the step and a Monte Carlo result kept through a colour change, its undo and redo; autosave and reload, Graph JSON export, an invalid file value dropped with the element kept; a share link's codec; the four layers at once on one Register, read from the pixels; a faint colour keeping the structure line; a selected coloured edge over its underlay and a state edge still dashed; Focus mode dimming; forced colours drawing no flow colour; the pinned surface and state colours against the computed tokens of both themes, and no frame token holding a palette value.
- `e2e/flow-colour-mobile.spec.ts` (`mobile` project) — a desktop-set colour renders on the phone; the read-only sheet shows the Colour section with every control disabled.
- `e2e/flow-colour-mobile.spec.ts` (`mobile` project) — a desktop-set colour renders on the phone; the read-only sheet shows the colour as one line of text with no control: a palette colour's dot, name and hex, another colour's dot and hex, Default with an empty ring, Mixed with no dot.
- `e2e/flow-colour-views.spec.ts` (PR 2) — the minimap marks and the timeline series (lines and legend) of coloured nodes take their colours while every other mark and series keeps its own, Registers stay dashed and an edge colour reaches neither; the run and its CSV are identical with and without colours; under forced colours both views equal the uncoloured graph's, and leaving forced colours brings the colours back; each colour offered once with the current one pressed once; a locked canvas showing the hex field and the colour input disabled, like the Label field, and the swatches with their colour; each of the three Templates opening with exactly its file's colours on the canvas and the minimap.
- `e2e/flow-colour-visual.spec.ts` — baselines of every kind and both edge kinds coloured, light and dark, L2 and L0, and every state at once.
- `e2e/flow-colour-views-visual.spec.ts` (PR 2) — baselines of the minimap and the timeline of a coloured graph, light and dark; the same two under forced colours, back on their kind and series colours; each coloured Template's fit view with its minimap, light and dark (the React Flow attribution masked in the canvas's own background). `e2e/flow-colour-mobile.spec.ts` adds the phone's one-line summary in pixels. Each colour offered once and the stored Recent order are held by DOM tests only.
- Every existing baseline whose only difference is the new selection ring or the edge underlay is updated and listed by name in the pull request.
- Not part of the done-when: a manual check of the browser's own colour dialog (it differs by browser and OS and cannot be opened by automation) and a manual screen-reader check.

Expand Down
2 changes: 1 addition & 1 deletion docs/mobile.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ The mobile layout is a **viewer + runner**. Precisely:
| structural keyboard shortcuts (undo/redo, duplicate, select-all, nudge) | same early-return |
| double-click / context-menu editing | `zoomOnDoubleClick={false}`; `onContextMenu` preventDefault on the canvas; no context menu wired |
| change any node/edge property | Inspector renders every field `disabled` / `readOnly` |
| change a flow colour (issue #325) | the Inspector's Colour section shows the current colour; its swatches, hex field and colour input are disabled with the rest of the sheet. A colour set on desktop renders on the phone (`docs/flow-colour-and-compact-nodes.md` FC-5) |
| change a flow colour (issue #325) | the Inspector's Colour section is one line of read-only text with no control: a dot and the colour's name and hex, the hex alone off the palette, Default with an empty ring, Mixed with no dot. A colour set on desktop renders on the phone, in the minimap and the timeline too (`docs/flow-colour-and-compact-nodes.md` FC-5, FC-6) |

**Allowed on mobile** (these are *not* structural graph mutations):

Expand Down
Loading
Loading