The embedded preamble had drifted from the qfd skill's reference: it
lacked the title-block machinery, section comments, and sizing notes.
Replace it verbatim so future edits don't fight stale scaffolding.
The corner header rendered plan.title in the 9rem name column, so it
collapsed to "..." — and the title already shows in the switcher, the
source, and the heading above the grid. Label its own column instead.
A fractional line box (0.8rem × 1.6) is rounded differently by the
textarea than by the <pre> backdrop, so the caret drifted further from
its glyph the lower it sat — worst at the bottom of a tall file.
The pattern's trailing optional quote let a complete `status = "x"`
match, so the popup reopened after the closing quote. Drop it so the
match ends with the value, while still typing remains supported.
Accepting an enum value (e.g. "on-track") re-ran the chained refresh,
which re-matched the value and reopened the popup. Chain only after
completing a key, when there are still values to offer.
Slicing the UTC ISO string showed the wrong calendar day near
midnight for non-UTC authors. Build it from local getFullYear/
getMonth/getDate so it matches the day the author actually sees.
The TOML editor offered nothing when typing a date, leaving the
yyyy-mm-dd format undiscoverable until a parse error. Suggest today
(a full, easy-to-edit date) and the current-year prefix on empty
date values and fresh reestimates elements, backing off once a date
is being typed.
The chosen layout is kept in the URL (?view=) so it's shareable and
bookmarkable rather than persisted. PNG export is disabled in
source-only mode since the rendered node it captures isn't mounted then.
Anchor a suggestion list at the caret (monospace metrics, re-anchored on
scroll), with arrow/Enter/Tab/Esc handling and click-to-accept. Accepting
a key like `status` chains straight into its value suggestions.
Given a source and caret offset, suggest block headers, the keys valid
for the current block (excluding ones already written), status enum
values, and the feature names referenced by a milestone's requires.
Mirrors the schema in parse.ts.
StatusLevel held green/orange/red — the RAG vocabulary CONTEXT.md
explicitly lists under _Avoid_ for the Status term, leaking a
presentation concern into the model and authored TOML. Replace with
on-track/at-risk/off-track; color now lives only in the renderer's
tone() mapping. Breaking change to authored .toml status values.
Add coverage for start/end extending, snapping, never-clipping, and the
empty-plan case. The bundled sample now demonstrates the keys, so its
expected week range moves to the authored bounds.
Optional top-level `start`/`end` dates widen the plan's week range with
lead-in / trailing columns. They only extend the auto-fitted range, never
narrowing it or clipping a Feature, so a momentarily-tight bound can't hide
work in progress.
Captures the full timeline (not just the scrolled viewport) by expanding
the grid to content width during render; clipboard write stays inside the
user gesture so Safari accepts it, with download as the documented fallback.
- milestones render as horizontal label flags, auto-stacked onto extra
rows with leader lines so labels in nearby weeks never collide
- "today" becomes a neutral grey column (mixed in oklab) and milestone
diamonds are grey too — red is reserved for problems (late, red status,
unmet counts), which no longer get a stray warm tint
- fix the name column to a stable width so the band aligns with the grid
- bar line begins/ends at a glyph centre — no stub past the first/last symbol
- glyph halos so the bar passes behind, not through, the symbols
- today's week is a shaded column instead of a vertical rule
- widen week columns so date labels stop colliding
- drop "slip" wording from the legend