@kenjura/ursa 0.90.0 → 0.93.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,57 @@
1
+ # 0.93.0
2
+ 2026-09-03
3
+
4
+ `menu-label` now renames a folder everywhere it appears, not just in the sidebar.
5
+
6
+ A folder could already override its menu label — `menu-label` in its `index.md` frontmatter, or `label` in its `config.json` — and the site-wide menu honoured it. Nothing else did. A folder called `bnw` labelled "BNW - Brave New World" in the sidebar was still "Bnw" in the auto-index listing of its parent, "Bnw" in the `<h1>` and `<title>` of its own generated index page, and "Bnw" in every breadcrumb trail passing through it. The label was doing a quarter of its job, and there was no way to fix the other three without renaming the folder on disk.
7
+
8
+ - **Auto-index listings resolve labels the same way the menu does**: `menu-label` frontmatter, then `config.json` `label`, then the folder name. This covers all three listing paths — the inline listing from `generate-auto-index: true`, the fallback index generated for folders without one, and the output-scanning variant.
9
+ - **Individual documents honour `menu-label` too**, so a single article can be renamed in a listing without renaming its file.
10
+ - **Auto-generated index pages take the folder's label** for their `<h1>` and `<title>`, instead of the raw folder name.
11
+ - **Breadcrumbs use folder labels** for every folder segment in the trail. The current page's own crumb now prefers its `menu-label` over its `title`; with neither, nothing changes.
12
+ - **`menu-sort-as` orders auto-index listings**, matching how it already orders the menu. Folders still sort ahead of files.
13
+
14
+ One naming change reaches folders with no label at all. Auto-index entries and breadcrumbs used to title-case names by lowercasing everything after the first letter, so a folder named `SoL` rendered as "Sol" and `WWII` as "Wwii". They now use the menu's own rule, which leaves interior capitals alone — the two places agree, and the disagreement they had was the bug.
15
+
16
+ The resolution rules live in `helper/menuLabels.js`, which the menu, the auto-index and the breadcrumbs all import, so the three cannot drift apart again.
17
+
18
+ Auto-index pages still have no dependency edge to the documents they list, so on a warm incremental rebuild a label edit in one folder does not regenerate a sibling listing that names it. That predates this change — adding or renaming a document went stale the same way — and `--clean` or a full generate is unaffected.
19
+
20
+ # 0.92.0
21
+ 2026-08-27
22
+
23
+ Upgrading ursa now invalidates the build cache, so an upgrade takes effect without `--clean`.
24
+
25
+ `.ursa/` caches a content hash per source document, and a document whose hash is unchanged is skipped entirely. But the hash only describes the *source*. It says nothing about the templates, renderers and asset bundles that turned that source into HTML — all of which live in ursa itself. So installing a new ursa over a warm cache left every unchanged document frozen at whatever the previous version produced: new template markup didn't appear, renderer fixes didn't apply, and even the ursa version in the page footer stayed at the old number. The workaround was to remember to run `--clean` after every upgrade, which is most of what made `--clean` feel mandatory in the first place.
26
+
27
+ - **`.ursa/` is stamped with the ursa version that wrote it.** On a mismatch the whole directory is discarded — hashes, dependency graph, nav cache and search index together — and the build starts cold. Upgrades and downgrades both count; so does a cache left by a version too old to have written a stamp, and a stamp that can't be parsed.
28
+ - **Matching stamps cost nothing.** A warm rebuild on the same version still skips every unchanged document, exactly as before.
29
+ - **`--clean` is unaffected**, and leaves behind a stamp the next run accepts, so it no longer costs an extra cold build.
30
+
31
+ This was the last unimplemented rule in the 0.76.0 cache-invalidation list; the other four (document, inherited `style.css`/`menu.md`, template, static asset) were already in place.
32
+
33
+ # 0.91.0
34
+ 2026-08-27
35
+
36
+ Ursa's built-in CSS is scoped with `@scope` and layered with `@layer`, so a site's own stylesheet no longer has to fight it.
37
+
38
+ Styling a site had turned into a specificity war. Ursa's stylesheet is loaded before the site's, but it styles content through selectors like `article#main-content h1` — an ID and two elements — so a site author writing the obvious `h1 { … }` lost, and kept losing until they either copied Ursa's selectors or reached for `!important`. Worse, rules meant for the frame leaked into documents and rules meant for documents leaked into the frame, because everything shared one flat global scope.
39
+
40
+ - **Content styles are layered.** Everything Ursa applies to a document body — headings, images, figures, the article box, the sticky headings — now lives in `@layer ursa.content`. A site's `style.css` is unlayered, and an unlayered declaration beats a layered one regardless of specificity, so `h1 { position: static }` or `#main-content { width: 1000px }` in a site stylesheet simply wins, at any specificity.
41
+ - **Chrome is scoped, not layered.** The top bar, menus, widgets, search and footer sit in `@scope (body) to (#main-content > *, article > *, .ursa-unstyled)`, so none of it can reach into a document's own markup — and, being unlayered, a stray `a { … }` in a site stylesheet still can't wreck the navigation. Chrome's selectors are unchanged, so overriding them works the way it always did — with a more specific selector, since a scoped rule now wins a specificity tie against an unscoped one. Breadcrumbs, the image hover controls and the lightbox get their own scopes on the same terms, since they are Ursa's furniture even though they render inside — or on top of — the document.
42
+ - **`class="ursa-unstyled"`** on any element puts it and everything inside it outside every one of Ursa's scopes. Not "override the defaults" — Ursa's CSS does not apply in there at all, down to the strike-through on dead links. The lightbox leaves images in there alone too, rather than injecting controls it has no styles for.
43
+ - **Nothing looks different.** The reorganisation is a pure cascade change. Verified by diffing every computed property and every bounding box of every element, before and after, across four pages, both colour schemes, desktop and mobile widths, and eight interaction states (top menu, collapsed and open side menu, stuck headings, open widgets, search results, inactive links, open lightbox): zero differences outside `.ursa-unstyled`.
44
+
45
+ Requires `@scope`: Chrome 118+, Safari 17.4+, Firefox 128+.
46
+
47
+ # 0.90.1
48
+ 2026-08-29
49
+
50
+ Upgraded `sharp` to the current 0.34 line and updated install-script allowlisting for pnpm.
51
+
52
+ - `sharp` is now `^0.34.5`.
53
+ - Added `sharp` to `pnpm.onlyBuiltDependencies` so its native install step runs consistently in pnpm-managed environments.
54
+
1
55
  # 0.90.0
2
56
  2026-08-26
3
57
 
package/README.md CHANGED
@@ -216,6 +216,41 @@ your-project/
216
216
  └── output/ # Generated site (created automatically)
217
217
  ```
218
218
 
219
+ ## Styling a Site
220
+
221
+ Drop a `style.css` (or `style-ursa.css`, or `_style.css`) in any source folder and it applies to every document in that folder and below. Every such file from the docroot down to the document's own folder is included, nearest last, so a deeper file overrides a shallower one.
222
+
223
+ Ursa's own stylesheet is scoped and layered so that your CSS wins without a fight:
224
+
225
+ - **Document content** — headings, images, figures, the article box itself — is styled inside `@layer ursa.content`. Your stylesheet is unlayered, and an unlayered rule beats a layered one no matter how specific it is, so a plain `h1 { position: static }` or `#main-content { width: 1000px }` overrides whatever Ursa sets. No `article#main-content h1` escalation, no `!important`.
226
+ - **Chrome** — the top bar, menus, widgets, search, footer, breadcrumbs, image hover controls and lightbox — is scoped but *not* layered, so a broad rule like `a { color: … }` in your stylesheet cannot bleed into the navigation. Overriding chrome works as it always did: use a more specific selector than the built-in one.
227
+ - **Nothing built in reaches into content it shouldn't.** Chrome rules stop at the article's children; content rules stop at the article's edge.
228
+ - **`class="ursa-unstyled"`** on any element puts it and its descendants outside every one of Ursa's scopes — none of Ursa's CSS applies in there at all, and the lightbox leaves images in there alone.
229
+
230
+ This uses the CSS `@scope` and `@layer` rules: Chrome 118+, Safari 17.4+, Firefox 128+.
231
+
232
+ ### Styling one widget at a time
233
+
234
+ The two widget panels are shared containers — the right-hand one holds the table
235
+ of contents, search and profile in turn — so styling `.widget-dropdown` styles
236
+ all of them at once. While a panel is open it carries `data-active-widget` naming
237
+ whichever widget is showing, and the attribute is removed when it closes, so a
238
+ site can give each one its own treatment:
239
+
240
+ ```css
241
+ /* Only the table of contents; search and profile keep the default panel. */
242
+ .widget-dropdown[data-active-widget="toc"] {
243
+ background: rgba(20, 24, 28, 0.78);
244
+ backdrop-filter: blur(10px);
245
+ }
246
+ ```
247
+
248
+ Both panels carry it: `#widget-dropdown` for the right-hand widgets (`toc`,
249
+ `search`, `profile`) and `#widget-dropdown-left` for the left-hand ones
250
+ (`recent-activity`, `suggested`). The value is the widget's `data-widget` name.
251
+ Ursa uses this hook itself, to lay the TOC out along the bottom of the viewport
252
+ on a narrow screen.
253
+
219
254
  ## Auto-Index Generation
220
255
 
221
256
  Ursa automatically generates index pages for folders that don't have one. You can also explicitly control auto-index generation in your index documents using frontmatter: