Dashboard navigation and child pages¶
The Dashboard (dash.md, alias Dashboard) is the calm place to choose
work, review its health, and open supporting collection and task pages.
Its navigation sits immediately after # Dash, above ## Tasks, as
three labeled rows in exact reading and keyboard order: Review, Work,
Browse.
| Group | Badges, left to right | Purpose |
|---|---|---|
| Review | NEW ยท ROTTEN ยท CROWDED | Intake, aging work, crowded notes |
| Work | TODAY ยท PENDING ยท NEXT ยท READY | Today's plan and the actionable lanes |
| Browse | PROJECTS ยท REFERENCES ยท BLOCKED ยท STATS โ | Open supporting collection and task pages |
Grouping is navigation only. It never changes the freshness walk, lane semantics, caps, or review sequence, and the Projects collection badge is not the freshness PROJECTS tier.
Work badge colors¶
TODAY, PENDING, NEXT, and READY use the same count-to-limit colors in daily bob-plan
blocks and on dash.md. Counts and limits use exact integer comparisons, never rounded
displayed percentages. For an available nonnegative integer count n and positive
integer limit L, the colors are:
| Condition | Color |
|---|---|
n === 0 |
grey |
0 < n < 2 * L / 5 |
blue |
2 * L / 5 <= n < 3 * L / 5 |
green |
3 * L / 5 <= n < 4 * L / 5 |
yellow |
4 * L / 5 <= n < L |
orange |
n === L |
magenta |
n > L |
red |
Check zero, strict excess, and exact equality before descending through 80%, 60%, and
40%. Small caps skip bands: cap 1 goes grey โ magenta โ red, and cap 3 goes blue โ
yellow โ magenta. Orange first appears at cap 5 (4/5). A NEXT section at 15/15 is
magenta even when a larger whole lane makes it over the whole-lane cap; that condition
remains informational and does not make the section over.
TODAY uses budget.links for its count and limit. Themes over their cap still override
TODAY to red; themes exactly at cap leave the link-based color intact. A missing ledger or
invalid count remains unavailable (โ). Orange (80% up to the cap) and magenta
(exactly at the cap) are presentation states, not lints or over conditions. Magenta
marks a lane that is exactly full, and no other Bob chip uses that hue.
Daily bob-plan PENDING/NEXT/READY badges use the same live section counts and colors,
including on older daily notes; older notes retain their own TODAY ledger but use current
live PENDING/NEXT/READY counts. CLI warnings and navigation notices continue to check
the whole lane, including TODAY, while daily bob-plan cap lint lines follow the
displayed section counts. An unavailable count remains โ with neutral styling
and unavailable accessibility text; it is never converted into numeric zero. Missing
ledger data or a missing Pomodoros section remains unavailable, rather than a synthetic
0/limit.
NEW, ROTTEN, and CROWDED share one Review count rule: muted grey with 0 โ when the
count is zero, red for every positive count, and โ when unavailable. ROTTEN follows its
displayed count even below the escalation threshold or after the upkeep budget is met.
BLOCKED is informational and has no cap. Its count stays available for navigation and uses the same informational accent as PROJECTS and REFERENCES regardless of its size.
Child pages¶
Root-level notes with hierarchy from frontmatter parent: "[[dash]]":
dash_projects.md(alias Dashboard Projects):# Projects,[[dash|โ Dashboard]], one short active/waiting description, and![[projects.base#๐ Active & Waiting]].dash_references.md(alias Dashboard References):# References,[[dash|โ Dashboard]], one short reading-queue description, one empty```bob-reading-boardfence, and![[refs.base#๐ Reading Queue]]. The board is a read-only kanban (Reading, Next, Ready, Snoozed) drawn frombob ref listJSON; the table follows it. The REFERENCES badge still counts the Reading Queue Base view, not the board. The board's fence, lanes, and keys are in ref.md. The Open Reading Board command opens this page, as Open Stats opensdash_stats.dash_stats.md(aliases Stats, Dashboard Stats):# Stats,[[dash|โ Dashboard]], one short derived-metrics description, and one empty```bob-statsfence. The Browse row ends with a label-onlySTATS โchip (no count) with the same chip chrome, hover preview, and click/Enter/Ctrl-click behavior as the other Browse chips. The block draws the schema-1 report frombob stats; metric meanings, the review journal, and CLI options live in stats.md. The daily-note counterpart is the Day strip.
Neither child carries type: [[project]], and no project or reference
note moves. The two .base files keep all views, filters, columns,
formulas, grouping, and sorting. The badge always describes the child's
default view, even if a visit switches the embedded table elsewhere.
Count scopes¶
- PROJECTS links to
dash_projects: project notes in the Active & Waiting view, counted once per path. Tooltip:N projects in Active & Waiting. Open Projects. - REFERENCES links to
dash_references: Markdown reference notes in the Reading Queue, counted once per path. Tooltip:N references in Reading Queue (next, wip, ready). Open References.
A successfully evaluated empty view is 0. Incomplete metadata, a
failed source read, or an unrecognized view contract is โ with a
short reason in the tooltip and accessibility label. One unavailable
collection never hides the other collection or any task badge.
Collection size is informational and never turns red.
Source and view contract guard¶
api.dashboardCollections (namespace v1, top-level api stays v3)
mirrors the two default views without a general Bases interpreter.
Project type must resolve through Obsidian's link resolver to
project.md; a list type never counts. Project status follows Bases
containsAny (scalar substring, list exact elements). References use
exact case-sensitive status equality, the exact ref/ prefix, and the
Markdown extension. No task-only Today, hide, freshness, schedule, or
dependency filters apply to either collection.
The plugin parses both .base files with the existing Obsidian
parseYaml dependency and validates only membership-affecting
structure, including any result limit, tolerating presentation-only
changes. A changed filter or renamed view marks that collection
unavailable instead of advertising a stale count. Predicate and
contract support must be extended together for a future filter change.
Base definitions load asynchronously outside the synchronous
snapshot(); metadata and vault events refresh open badges after a
short debounce, stale async completions are discarded, and widgets are
keyed by owning component and kind with cleanup on unload. There is no
per-badge polling, and eval, table DOM scraping, and private Bases
query APIs are never used.