All projects Linea · Write-up
A plan on metro lines, shared by a linkEin Plan auf U-Bahn-Linien, per Link geteilt
Linea draws a plan the way a metro map draws its lines: each lane a line, each bar a section with a stop at either end, each milestone a station. Everything moves by dragging, with a mouse or a finger, and two links share it, one to plan together, live, and one to look.Linea zeichnet einen Plan so, wie ein U-Bahn-Plan seine Linien zeichnet: jede Bahn eine Linie, jeder Balken ein Abschnitt mit einem Halt an jedem Ende, jeder Meilenstein eine Station. Alles bewegt sich durch Ziehen, mit der Maus oder dem Finger, und zwei Links teilen ihn, einer, um gemeinsam und live zu planen, und einer zum Ansehen.
- Type
- Web appWeb-App
- Stack
- Svelte 5 · Node · SQLite
- Year
- 2026
- Code
- Public on GitHubÖffentlich auf GitHub
A plan drawn as a metro map
Linea is a timeline for plans: lanes for the parts of a project, bars for the work in them, milestones for the dates that matter. It draws them the way a metro map draws its lines. Every lane is a line with its badge, M1, M2, M3, every bar a solid section with a stop at either end, every milestone a station. Where two bars in a lane overlap, the later one moves to a parallel track, and each lane takes as many tracks as it needs, so nothing is ever drawn over something else. A name too long for its bar sits beside it. Today is a red line with its tag, and the axis counts days, weeks or months under their months, quarters or years, whichever suits the zoom.
A new timeline starts with three empty lanes, or with an example, a shop relaunch over five months, to try things on. A plan saved as a file opens as a new timeline too.
With a mouse and with a finger
Everything on the plan moves by dragging. Drag across an empty stretch of a lane to draw a bar and type its name; drag a bar to move it in time or into another lane; grab the stop at either end to stretch it. A lane has a grip to put it in another order. While something moves, a tag beside it shows its dates, and the plan scrolls when the pointer reaches its edge. Zoom with a pinch, with ⌘ or Ctrl and the wheel, or with Week, Month, Quarter and Year; a pinch keeps the day under the fingers where it is.
On a phone a finger has to scroll the plan, so a drag waits for a press: hold a bar for a third of a second and it lifts, then follows the finger. A tap opens the bar’s details in a sheet from the bottom, with a day earlier or later on each date, its lane, its colour and a note, and the round button adds a bar in the middle of the screen. The desktop has the keyboard: the arrows move the selected bar a day, a week with Shift, Backspace deletes it, ⌘D duplicates it, Enter renames it, and ⌘Z takes back your own last step, not someone else’s.
Two links instead of accounts
There is no sign-in. Every timeline has two links, and whoever has one gets what it says. The edit link changes the plan. The view link shows every change as it happens and changes nothing: its page has no handles, and the server refuses a change sent with it. Each link carries a key of 128 random bits, so it can’t be guessed. If one reached the wrong people, Make new links replaces both, and the old ones stop working for everyone at once. The timelines you’ve opened are listed on your device, newest first; removing one there only forgets it.
The keys stay out of everything else. The pages and the API ask search engines not to index them, and Census, the family’s visit counter, sees /e and /v without the key: Linea’s server strips it before it passes the visit on.
Live, one change at a time
Every change is a small operation: add a bar, set a bar’s start and end, move a lane, rename the plan. The page applies it at once and sends it to the server, which numbers it and passes it on to everyone with the timeline open, over a stream of server-sent events. When two people change the same bar, the later write wins for each field it sets, so one person moving a bar while another renames it keeps both. A page that loses its connection picks up where it left off: the server keeps the last 500 operations and sends the ones it missed, or the whole plan when it missed more. While offline, the last copy stays on the screen to read, and the page says so.
The faces in the header are the people with the timeline open, under the name each one set, which the family’s other apps share, and a bar someone is dragging wears their name until they let go.
Part of the family
A plan leaves the app as a picture, the whole plan on white for a slide, or as a file to keep and open again as a new timeline. The server has no dependencies: Node’s own HTTP and its built-in SQLite, one table for the timelines and one for their operations, on the NAS. It sends a strict Content Security Policy, and the page talks only to its own address. The tokens and components come from Folio, the family’s shared library, and the visit counter, Census, works without cookies.
Ein Plan als U-Bahn-Netz
Linea ist eine Zeitleiste für Pläne: Bahnen für die Teile eines Projekts, Balken für die Arbeit darin, Meilensteine für die Termine, auf die es ankommt. Sie zeichnet sie so, wie ein U-Bahn-Plan seine Linien zeichnet. Jede Bahn ist eine Linie mit ihrem Schild, M1, M2, M3, jeder Balken ein Abschnitt mit einem Halt an jedem Ende, jeder Meilenstein eine Station. Wo sich zwei Balken einer Bahn überschneiden, rückt der spätere auf ein paralleles Gleis, und jede Bahn bekommt so viele Gleise, wie sie braucht, damit nie etwas über etwas anderem liegt. Ein Name, der zu lang für seinen Balken ist, steht daneben. Heute ist eine rote Linie mit ihrem Schild, und die Achse zählt Tage, Wochen oder Monate unter ihren Monaten, Quartalen oder Jahren, je nachdem, was zum Zoom passt.
Eine neue Zeitleiste beginnt mit drei leeren Bahnen oder mit einem Beispiel, einem Shop-Relaunch über fünf Monate, zum Ausprobieren. Ein als Datei gespeicherter Plan öffnet sich ebenfalls als neue Zeitleiste.
Mit der Maus und mit dem Finger
Alles im Plan bewegt sich durch Ziehen. Über ein leeres Stück einer Bahn ziehen zeichnet einen Balken, dann seinen Namen tippen; einen Balken ziehen verschiebt ihn in der Zeit oder in eine andere Bahn; den Halt an einem seiner Enden greifen dehnt ihn. Eine Bahn hat einen Griff, um sie umzusortieren. Während sich etwas bewegt, zeigt ein Schild daneben seine Daten, und der Plan scrollt, wenn der Zeiger seinen Rand erreicht. Zoomen geht mit zwei Fingern, mit ⌘ oder Strg und dem Mausrad oder mit Woche, Monat, Quartal und Jahr; beim Zoomen mit zwei Fingern bleibt der Tag unter den Fingern, wo er ist.
Auf dem Handy muss ein Finger den Plan scrollen können, also wartet das Ziehen auf einen Druck: Einen Balken eine Drittelsekunde halten, dann hebt er sich und folgt dem Finger. Ein Tippen öffnet die Details des Balkens in einem Blatt von unten, mit einem Tag früher oder später an jedem Datum, seiner Bahn, seiner Farbe und einer Notiz, und der runde Knopf legt einen Balken in der Mitte des Bildschirms an. Am Desktop gibt es die Tastatur: Die Pfeile verschieben den gewählten Balken um einen Tag, mit Umschalt um eine Woche, die Rücktaste löscht ihn, ⌘D dupliziert ihn, Enter benennt ihn um, und ⌘Z nimmt den eigenen letzten Schritt zurück, nicht den von jemand anderem.
Zwei Links statt Konten
Eine Anmeldung gibt es nicht. Jede Zeitleiste hat zwei Links, und wer einen hat, kann, was er sagt. Der Bearbeiten-Link ändert den Plan. Der Ansehen-Link zeigt jede Änderung, sobald sie passiert, und ändert nichts: Seine Seite hat keine Griffe, und der Server lehnt eine Änderung ab, die mit ihm kommt. Jeder Link trägt einen Schlüssel aus 128 Zufallsbits, er lässt sich also nicht erraten. Ist einer an die Falschen geraten, ersetzt „Neue Links erstellen“ beide, und die alten funktionieren für niemanden mehr, sofort. Die schon geöffneten Zeitleisten listet das eigene Gerät, die neueste zuerst; eine dort zu entfernen, vergisst nur den Eintrag.
Aus allem anderen bleiben die Schlüssel heraus. Die Seiten und die API bitten Suchmaschinen, sie nicht aufzunehmen, und Census, der Besuchszähler der Familie, sieht /e und /v ohne den Schlüssel: Lineas Server entfernt ihn, bevor er den Besuch weitergibt.
Live, eine Änderung nach der anderen
Jede Änderung ist eine kleine Operation: einen Balken anlegen, Anfang und Ende eines Balkens setzen, eine Bahn verschieben, den Plan umbenennen. Die Seite wendet sie sofort an und schickt sie an den Server, der sie nummeriert und an alle weitergibt, die die Zeitleiste offen haben, über einen Strom von Server-Sent Events. Ändern zwei Leute denselben Balken, gewinnt für jedes Feld das spätere Schreiben, so bleibt beides erhalten, wenn eine Person einen Balken verschiebt und eine andere ihn umbenennt. Eine Seite, die ihre Verbindung verliert, macht dort weiter, wo sie aufgehört hat: Der Server behält die letzten 500 Operationen und schickt die verpassten, oder den ganzen Plan, wenn es mehr waren. Offline bleibt die letzte Kopie zum Lesen auf dem Bildschirm, und die Seite sagt das.
Die Gesichter in der Kopfzeile sind die Leute, die die Zeitleiste offen haben, unter dem Namen, den jede und jeder gesetzt hat und den die anderen Apps der Familie teilen, und ein Balken, den jemand gerade zieht, trägt dessen Namen, bis er losgelassen wird.
Teil der Familie
Ein Plan verlässt die App als Bild, der ganze Plan auf Weiß für eine Folie, oder als Datei zum Aufheben und Wiederöffnen als neue Zeitleiste. Der Server hat keine Abhängigkeiten: Nodes eigenes HTTP und sein eingebautes SQLite, eine Tabelle für die Zeitleisten und eine für ihre Operationen, auf dem NAS. Er schickt eine strenge Content Security Policy, und die Seite spricht nur mit ihrer eigenen Adresse. Tokens und Komponenten kommen aus Folio, der gemeinsamen Bibliothek der Familie, und der Besuchszähler Census kommt ohne Cookies aus.