Keep a place, and come back to it

The map had no memory. Every visit started at the same overview, and a system
worth returning to had to be found again by name each time. A mark on the
readout and on a body's panel now keeps it, a Bookmarks tab lists what has
been kept, and choosing one goes there — a star by flying into its system, a
body by opening its page.

Local storage, not an account. This map asks nobody to sign in, and a list of
stars somebody liked is not worth a server. Every read of that store is
defensive, because it is a string a person can edit, another tab can write,
and a browser can refuse to hand over at all: a bad entry is skipped rather
than losing the rest, duplicates are collapsed since two entries for one place
would each toggle the other's control, the list is bounded so a hand-edited
store cannot decide how much this renders, and where storage is denied
outright the bookmarks still work for the visit — they just do not outlive it.

The name is stored alongside the id rather than looked up. That way the list
reads before the catalogues have loaded, and a bookmark to something a later
catalogue no longer holds still says what it was instead of decaying into a
bare number.

The tab is offered even when it is empty, and says what the mark does. A tab
that appears only once you have already found the feature is a tab that never
taught anyone anything.

Choosing a kept place hands the panel back to the readout, which is the same
move as choosing a search result and for the same reason: the panel has done
its job and the thing to look at is now the scene. That behaviour is what the
end-to-end spec caught missing — the readout it asserted on did not exist,
because the panel that had just been used was still covering it.

Verified: build clean, 587/587 unit, 11/11 end-to-end including a spec that
keeps Earth, leaves the page, comes back to it from the list and forgets it,
and one that keeps Proxima Centauri, flies out to the field and flies back in
by what was kept. Design detector clean, screenshots at 1440x900 and 390x844.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
This commit is contained in:
2026-08-20 19:07:46 +02:00
co-authored by Claude Fable 5
parent 68a919bd84
commit bd3a5a48c9
10 changed files with 513 additions and 18 deletions
@@ -0,0 +1,22 @@
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
/**
* The mark on a place worth coming back to. Hollow when it is not kept, filled when it is —
* the same two states as the Display panel's layer ticks, which is where the eye has already
* learned what a filled mark means here.
*
* Size and colour come from the classes on the host; the svg fills it.
*/
@Component({
selector: 'app-bookmark-icon',
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'block', 'aria-hidden': 'true' },
template: `
<svg class="h-full w-full" viewBox="0 0 24 24" [attr.fill]="kept() ? 'currentColor' : 'none'" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round">
<path d="M7 4h10v16l-5-4-5 4z" />
</svg>
`
})
export class BookmarkIconComponent {
readonly kept = input(false);
}