v1.1.0
The first minor since 1.0: a category can be wider than one column. DASHBOARD_RELEASE and NEXTDASH_WHATS_NEW_DATA_VERSION are bumped, so the modal reopens once.
Categories across columns
- new —
Category.Spread(spreadinbookmarks-{page}.json) marks a category as allowed to run across grid columns; uncategorized and the smart collections keep theirs insettings.categorySpreads[pageId][categoryId], the shapecategorySortModesalready uses.dashboard-category-span.jsowns both, so no caller has to know which applies. - new — the width itself is derived, never stored:
spanForCountismin(ceil(count / categoryItemLimit), effectiveColumns, 12). It was a number the user picked in the first draft; it became a switch because the number is implied by two settings that already exist, and a stored number goes stale the moment a bookmark is added. - new —
applyCategoryItemLimitmultiplies the limit by the span, so a spread category shows its limit once per column and stays the height of its neighbours.refreshAllCategorySpansruns fromfinishIncrementalRefresh, which is what makes an added bookmark bring the next column with it rather than waiting for a reload;settleSpanChangefollows that through to the "+ N more" cut and, in packed mode, to a full re-render. - new — the two settings rule out each other's extreme:
spreadUnavailableReasonreturnsunlimited-itemswhencategoryItemLimitis 0, and the config select disables Unlimited whileanySpreadCategoryholds. Both say why where they are asked for. - new — routes:
DashboardCategoryMenu(entry flips to Back to one column, noaria-checkedbeside a label that already flips),Shift+Winkeyboard-navigation.js,:width on|off|all, adata-cat-spreadbutton per row in the categories editor, andAppearance → Layout → Categories across columnsfor the defaults and the reset. - new —
.category--widespans withgrid-column: span var(--category-span)and repeats the row's track pattern once per column, sosubgridalignment survives. The inner column gap is the grid gap plus2 × --category-inline-pad: a run of categories pads every column on both sides, a single wide box only its outer edges, and without that the inner columns sat 16px left of the grid.syncWideColumnTrackspins the shortcut and lead tracks, which are intrinsic and were sized per repeat by whichever rows happened to land in them. - new — a rule under the header spanning the block, and a
↔Nbadge in the header, both dropped while the category is collapsed or one column wide.
Packed columns
- new — packed keeps its round-robin flex columns while nothing spreads, and switches to a grid (
packed-masonry) the moment something does:--masonry-spanrows per category fromdashboard-packed-masonry.js,grid-auto-flow: row dense, aResizeObserverper category. Bands were tried first and left a hole the height of the tallest column beside the wide block. - fix —
syncCategoriesFromDomread the columns in document order while the render filled them round-robin. Those are not each other's inverse, so every category drag rewrote the order into one that redistributed differently and scrambled the page.readCategoryElementsInOrderis the single inverse now, keyed on what is in the DOM, andgetExistingCategoriesdelegates to it. - fix —
syncDashboardGridLayoutrebuildsclassNamewholesale and droppedpacked-masonry, so any settings refresh — including the one behind a window resize — left the categories as bare flex children of a row with no columns in it.
Config
- fix — the location memory was written only on the exits config knows about; the header's health, inbox and page buttons switch view around it.
restoreConfigHashnow saves on every move inside config andsetActiveViewstamps it on the way out. The TTL is 5 minutes (DashboardConfigandDashboardConfigLoaderboth), counted from leaving rather than from the last click inside. - new —
type: 'action'panel controls withbindPanelActions, used for Turn spreading off everywhere;NEW_THIS_RELEASEis the one place naming where the twinkle points, drawn on the section, the sub-tab and the panel. - new —
#category-context-menusizes to its content (width: max-content, capped at 24rem). The shared.move-popovercap is for the move/tag/delete pickers; at 16rem the widest row here needed 274px and got 237, so theShift+Wchip was trimmed away — and the French label is half again as long.
Config → Bookmarks
- new — the section gets the sub-tab strip five others already have: List and Settings. The nine settings sat after the list — fifty rows down by default and up to five hundred as the infinite scroll loads more, which also rules out jumping to the bottom of a list whose bottom moves as you approach it. Registered in
SUB_TABS,SUB_TAB_STATE,SUB_TAB_ATTRandSUB_TAB_SECTION, so the deep link, the remembered location and the arrow-key walk come for free;handleOverviewGoacceptsbmTab.
Views
- new — Health, Inbox and Config → Bookmarks draw one card from
feed-row.cssinstead of three copies. The rule was written out inhealth-view.css,dashboard-inbox.cssandconfig-view.cssand the copies had drifted into being byte-identical — one design, three places to change it, and no way to tell whether a difference was meant. What genuinely differs is a modifier:feed-row--with-selectfor Health's checkbox column, and the coloured left edge each view uses for its own state, including modern layout's inset redraw of it. Classic layout also gains the row focus ring only modern had. - new — the shape the three views disagreed on is settled: Inbox rounded its filter pills and buttons where Health squared them off; rounded won. Config → Bookmarks reads as a view rather than a settings panel — a header with a count, the search box sized like Health's, and tiles matching Health's without the stripe.
Discoverability
- new —
spread-notice.js(aNoticeCard) andspread-tutorial.js, a four-stepAppModalwalkthrough in the shape of the inbox and health tours, reachable afterwards fromHelp → Pages & categories. - fix —
NoticeCardbound an action withquerySelector, and a card naming its × throughdismissNameputs that attribute on the × as well. The × comes first, so it took the handler and the button sharing its name got none: the side rail's No thanks had been dead since the cards were unified.
Docs
MANUAL.md— the spreading section with the columns-per-bookmark-count table, and the config-memory paragraphs at five minutes. Config → Bookmarks is described with its two sub-tabs.README.md— the feature bullet,Shift+W,:width on|off, and the five-minute memory.CHANGELOG.md,static/data/whats-new/v1.1.0.json,index.json,whats-new-stub.js,tests/whats-new-hidden-release.spec.js, the four locale files, andgo generate ./...forasset_hashes_gen.go.