@hraness/design-kit 0.40.3 → 0.41.1

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/HERO_FIELDS.md CHANGED
@@ -48,7 +48,9 @@ and their types are marked deprecated. Remove them when convenient.
48
48
 
49
49
  A product that still passes decorative artwork should delete it rather than
50
50
  recreate it in product CSS. Floating or blurred elements behind the heading make
51
- it harder to read, especially on phones.
51
+ it harder to read, especially on phones. The one page-level drawing the kit
52
+ supports is a [product landscape](LANDSCAPE.md), which sits in the margins
53
+ behind the whole page rather than behind the hero copy.
52
54
 
53
55
  `ProductHero` stays available from the server entry and no longer crosses a
54
56
  client boundary. The `@hraness/design-kit/react/hero-backdrop` export remains a
package/LANDSCAPE.md ADDED
@@ -0,0 +1,100 @@
1
+ # Product landscape
2
+
3
+ A product landscape is one detailed drawing of the product's world, drawn
4
+ behind its marketing, documentation, and blog pages. It is the one sanctioned
5
+ exception to the Quiet direction's flat page background. The drawing stays in
6
+ the margins, takes its colour from the page's own text and background, and
7
+ tiles down the page, so it never competes with the copy and never runs out on
8
+ a long page.
9
+
10
+ ## Supply the drawing
11
+
12
+ Give each product its own drawing. Prepare it as a grayscale luminance mask:
13
+ the drawing in light lines on black, with a quiet centre column where the copy
14
+ sits and both ends fading to black so the tiles meet without a seam. Export
15
+ WebP at three widths and name each file by its SHA-256 digest:
16
+
17
+ | Image | Width | Use |
18
+ | --- | --- | --- |
19
+ | Wide | 1920px | Desktop, 1x |
20
+ | Wide 2x | 2880px | Desktop, high-density screens |
21
+ | Narrow | 1170px | Phones up to 48rem |
22
+
23
+ Do not put text, logos, or colour in the drawing. The kit tints it for every
24
+ palette and appearance.
25
+
26
+ ## Turn it on
27
+
28
+ Import the stylesheet once. `styles.css` and `compiler-foundation.css` already
29
+ include it.
30
+
31
+ ```css
32
+ @import "@hraness/design-kit/product-landscape.css";
33
+
34
+ :root {
35
+ --hraness-landscape-image: image-set(
36
+ url("/landscape/landscape-<wide-digest>.webp") 1x,
37
+ url("/landscape/landscape-<wide-2x-digest>.webp") 2x
38
+ );
39
+ --hraness-landscape-image-narrow: url("/landscape/landscape-<narrow-digest>.webp");
40
+ }
41
+ ```
42
+
43
+ Use root-relative or absolute URLs: custom properties resolve relative URLs
44
+ differently across browsers.
45
+
46
+ Then mark every public page that should show it. `data-hraness-landscape="page"`
47
+ on `<body>` or on any element inside the page draws the drawing behind the whole
48
+ document, so a marketing page, a documentation shell, and a blog layout can
49
+ each opt in from their own markup:
50
+
51
+ ```tsx
52
+ <MarketingPage landscape="page">…</MarketingPage>
53
+ ```
54
+
55
+ `MarketingPage` emits the attribute from its `landscape` prop; any other
56
+ element takes the attribute directly.
57
+
58
+ Put `data-hraness-landscape="off"` anywhere on an application route that
59
+ shares the layout. Use `data-hraness-landscape="contained"` to draw it behind one
60
+ element instead, such as a section below a full-screen application.
61
+
62
+ | Property | Default | Meaning |
63
+ | --- | --- | --- |
64
+ | `--hraness-landscape-image` | none (draws nothing) | Wide mask, usually an `image-set()` |
65
+ | `--hraness-landscape-image-narrow` | the wide image | Mask at 48rem and below |
66
+ | `--hraness-landscape-opacity` | `0.5` | Layer opacity on wide screens |
67
+ | `--hraness-landscape-opacity-narrow` | `0.36` | Layer opacity on phones, where copy spans the drawing |
68
+ | `--hraness-landscape-strength` | `30%` | Share of the text colour mixed into the background for the ink |
69
+ | `--hraness-landscape-ink` | the mix above | Replace the ink entirely |
70
+ | `--hraness-landscape-radius` | `0.75rem` | Radius for solid and glass surfaces |
71
+
72
+ Forced colours and print never draw the layer.
73
+
74
+ ## Keep panels over the drawing soft
75
+
76
+ A hard-edged slab over a detailed drawing reads as a mistake. Under a
77
+ landscape, the kit adjusts its own surfaces:
78
+
79
+ - Page wrappers that repaint the page colour (`.hraness-marketing-page`, a
80
+ nested `.plain-site`, `.plain-footer`) become transparent, so the identical
81
+ body colour and the drawing show through.
82
+ - Reading surfaces stay opaque and get rounded edges: article code blocks and
83
+ tables.
84
+ - Small cards and callouts (marketing cards, quotes, plans, trust items,
85
+ interfaces, primitives, article callouts, and social kit items) become
86
+ frosted panels using the sticky header's material: 82% surface tint with
87
+ `blur(14px) saturate(1.4)`. Without backdrop support, under reduced
88
+ transparency, and in forced colours they keep their opaque surface.
89
+
90
+ Product-owned elements opt in with one attribute:
91
+
92
+ | Attribute | Use for |
93
+ | --- | --- |
94
+ | `data-hraness-landscape-surface="clear"` | A full-width wrapper or band painted in the page colour |
95
+ | `data-hraness-landscape-surface="solid"` | Code, tables, documentation sidebars, forms: opaque, rounded |
96
+ | `data-hraness-landscape-surface="glass"` | Small cards, callouts, and badges: frosted, rounded |
97
+
98
+ Set `--hraness-landscape-solid` or `--hraness-landscape-glass` on an element to
99
+ choose its base colour. Leave a deliberately coloured full-width band as it
100
+ is; it simply covers the drawing.
package/README.md CHANGED
@@ -11,7 +11,7 @@ Pin a GitHub release tag:
11
11
  ```json
12
12
  {
13
13
  "dependencies": {
14
- "@hraness/design-kit": "github:hraness/design-kit#v0.40.3",
14
+ "@hraness/design-kit": "github:hraness/design-kit#v0.41.1",
15
15
  "@hraness/ui": "github:hraness/ui#v0.5.17"
16
16
  }
17
17
  }
@@ -72,6 +72,27 @@ header titled “My workspace” above “Saved work”. `TopBar` renders a sema
72
72
 
73
73
  ## Release notes and focused examples
74
74
 
75
+ ### Quieter interface cards
76
+
77
+ Version 0.41.1 gives `MarketingInterfaceGrid` a shared `link` slot: pass `link: { href, label }` on any interface entry and the card renders the link at its bottom edge, aligned to the end, in the muted ink, so every card in the row keeps the same quiet reference link no matter how tall its example runs. Code inside interface cards sets at a smaller size, proof-frame chrome packs tighter, and `MarketingProofFrame` accepts `chrome="terminal"` or `chrome="window"` without a `title`; the chrome then shows only its window lights, dropping the generic "Terminal" label while keeping a named bar available when a real title is supplied. Existing call sites keep working: `link` is optional and a `title` still implies window chrome.
78
+
79
+ ### Product landscapes
80
+
81
+ Version 0.41.0 adds `product-landscape.css`: one product-specific drawing behind
82
+ the marketing, documentation, and blog pages. The product supplies a grayscale
83
+ luminance mask and the kit tints it from the page's text and background, tiles
84
+ it down the page so long pages never run out, swaps in a narrow image on
85
+ phones, and hides it in forced colors and print. Mark a page with
86
+ `data-hraness-landscape="page"` (or `MarketingPage` `landscape="page"`), turn it
87
+ off on application routes with `"off"`, or draw it behind one element with
88
+ `"contained"`. Over the drawing, page wrappers clear, code blocks and tables
89
+ stay opaque with rounded edges, and small cards and callouts become frosted
90
+ panels that turn opaque without backdrop support, under reduced transparency,
91
+ and in forced colors. Product elements opt in with
92
+ `data-hraness-landscape-surface="clear"`, `"solid"`, or `"glass"`. `styles.css`
93
+ and `compiler-foundation.css` include the stylesheet; nothing changes on a page
94
+ without a host. See [Product landscape](LANDSCAPE.md).
95
+
75
96
  ### Canonical install labels
76
97
 
77
98
  Version 0.40.3 keeps `SlopCamera` spelled consistently in install labels supplied by `@hraness/design-kit/portfolio`. The snapshot comes from registry commit `64d51361`; technical IDs, commands, and domains are unchanged.
@@ -432,6 +453,18 @@ Set `data-hraness-material="lantern"` on a themed host and apply the documented
432
453
 
433
454
  See the [material contract and examples](LANTERN_MATERIAL.md) for palette islands, portal hosts, accessibility fallbacks and the immutable installer. The gallery demonstrates light and dark workspaces with working search, selection and disclosures.
434
455
 
456
+ ## Draw a product landscape
457
+
458
+ `product-landscape.css` draws one product-specific drawing behind public pages:
459
+ a grayscale luminance mask tinted from the palette, tiled down the page, and
460
+ kept in the margins. Set `--hraness-landscape-image` on `:root`, then mark each
461
+ page with `data-hraness-landscape="page"` (`MarketingPage` takes
462
+ `landscape="page"`). Over the drawing, page wrappers clear, code and tables stay
463
+ opaque with rounded edges, and small cards and callouts become frosted panels
464
+ with opaque fallbacks. `styles.css` and `compiler-foundation.css` include it.
465
+ See [Product landscape](LANDSCAPE.md) for image preparation, the off switch,
466
+ contained hosts, tuning properties, and product surface hooks.
467
+
435
468
  ## Explain a technical product
436
469
 
437
470
  `product-marketing.css` is an opt-in narrative grammar for technical product
@@ -953,7 +986,7 @@ bun run browser:install
953
986
  bun run check
954
987
  ```
955
988
 
956
- The stable dependency pair for this release is `@hraness/ui` `v0.5.17` with `@hraness/design-kit` `v0.40.3`. Version 0.31.0 keeps the `limits` beat and beats marked `social: false` out of the social kit and adds `socialPost` for social wording that stands without a caveat. Version 0.30.3 refreshes the portfolio snapshot so related-product cards use each product's own spelling, such as GhostGet and TextButler. Version 0.30.2 keeps the narrow and stacked install-tab layout when another package compiles the same atoms into a later cascade layer. Version 0.30.1 keeps every PlatformInstall tab name whole in columns down to 200px by stacking each mark above its name, using a container query on the component. Version 0.30.0 adds `site-shell.css`, which keeps short-page footers at the viewport bottom. Version 0.29.3 preserves readable selected install tabs in forced colors. Version 0.29.2 keeps all three PlatformInstall tabs visible at 320 to 360px and draws each platform mark once per component. Version 0.29.1 keeps marketing action labels readable in forced colors. Version 0.29.0 adds `PlatformInstall`, one install block for every CLI site: a tab per operating system with its mark, the install command with a Copy button that announces the result, optional alternative commands such as npm or Homebrew, and a note for platforms without a native build. After hydration it selects the visitor's operating system; without JavaScript every command shows. It also adds `PlatformIcon` (Apple, Tux, and Windows marks in `currentColor`) and a `PlatformBadges` "Runs on" row, plus `platformLabel`, `platformMark`, `detectPlatform`, and `matchDetectedPlatform` at the package root. See [Install commands for each platform](#install-commands-for-each-platform). No existing export changes. Version 0.28.0 adds the launch kit. `@hraness/design-kit/mockups` draws labelled illustrations of chat, feeds, inboxes, articles, terminals, browsers, desktop windows, menu bars, and phones in server-safe plain React with no StyleX or React Aria, styled by `@hraness/design-kit/mockups.css`; each renders as one image with a text description and no headings. `@hraness/design-kit/mockups/client` adds `ModeShowcase`, `FitToWidth`, and `StepThrough`. `@hraness/design-kit/launch`, with no React, holds the `LaunchBeat`, `LaunchFacts`, and `SocialKit` shapes with `resolveLaunchBeats`, `buildSocialKit`, and `assertLaunchKit`. `@hraness/design-kit/testing` gives product repositories `blogConformance`, `renderMatrix`, `assertNoHeadings`, `assertRoleImgWithLabel`, and `assertFakeHandles`. The React entries add `ArticleFigure`, `ArticleVideo` with `articleVideoJsonLd`, `ArticleTable`, `ArticleBarChart`, `ComparisonTable`, `LaunchBeats`, and `SocialKitPanel`, and `MarketingProofFrame` takes `chrome` (`window`, `browser` with `url`, or `terminal`). [ARTICLE_COPY.md](ARTICLE_COPY.md) now writes "Introducing a product" as beats; the admission rules are unchanged. No existing export changes. Version 0.27.0 adds explicit Rust, TOML, YAML, Lean, and TLA+ code highlighting, including nested comments and multiline strings. The existing highlighter API and stylesheet remain the shared entry points; unsupported languages still render as escaped text. Version 0.26.0 adds `MarketingNotice` and the raw `.hraness-marketing-notice` class: one status or alert line (`info`, `success`, or `error`) that sits on the content edge of the page column instead of spanning the window. Errors are announced as alerts and other tones as status. Signed-in account pages that render inside `MarketingSiteHeader` should compose `MarketingMain`, `MarketingNotice`, `MarketingStatStrip`, and `MarketingSection` so every block shares the header's measure and gutter, rather than hand-rolled full-bleed banners and nested cards. Version 0.25.0 moves bordered foil surfaces off the spectrum: `.hraness-foil` and `[data-emphasis="primary"]` actions keep their flat surface fill under one theme-aware monochrome edge — black on light, white on dark, overridable through the new `--hraness-foil-edge` token — while the metallic spectrum stays on wordmarks and marks. The foil material contract advances to version 3: `surfaceImage` and `surfaceBackgroundClip` are replaced by `surfaceFill`, `edge`, `edgeDark`, and `edgeColor`. Reinstall any vendored marketing snapshot from the 0.25.0 commit. Version 0.24.0 joins a marketing footer directly followed by the shared `@hraness/site-footer` network footer into one band: the product row's bottom space collapses to a compact gap and the network row's content follows the marketing measure and gutter through `--hraness-site-footer-measure`, so product links and the organization row share one column instead of reading as two stacked bars. Mount the network footer directly after `MarketingSiteFooter`; no prop or markup change is needed inside either landmark. Version 0.23.0 moves marketing pages to the Quiet direction described in [DESIGN.md](DESIGN.md). `ProductHero` no longer renders a backdrop, `HeroBackdrop` renders nothing, and `attachHeroLight` is an inert disposer; their names and props stay so existing code compiles and are marked deprecated. The `cells`, `weave`, `contour`, and `mesh` patterns render as `none`, and marketing fields and Lantern walls paint the flat palette background. Both marketing presets use Nebula Sans for display headings (editorial at weight 550); Instrument Serif stays vendored for explicit opt-in only. Hero eyebrows are plain labels, the accent band loses its grid, and cards and header chrome use hairline edges instead of lifted shadows. On phones `MarketingSiteHeader` keeps the brand, primary action, and appearance menu on one row and moves the links to a second row that scrolls sideways, with 44px targets. To migrate, delete `backdrop` artwork, `HeroBackdrop`, `attachHeroLight`, pattern values, and product CSS that recreated textures or serif headings, then reinstall any vendored marketing snapshot from the 0.23.0 commit. Version 0.22.2 restores the canonical roughday mark — the rain-cloud artwork pinned by the portfolio registry — after the mark slot briefly carried a stray illustration. Version 0.22.1 completes the icon library with the roughday inline chip family (65 admitted assets, no pending members). Version 0.22.0 adds the `./icons` surface: 62 vetted single-ink assets across ten sets — a shared illustration family, product illustration families, and the product marks, each admitted through a measured gate (single ink, bounded aspect, coverage, stroke, paths, bytes) and per-set family coherence, distributed as a typed registry module (`hranessIcons`, `hranessIcon`, `hranessIconMarkup`, `hranessIconsForSet`) and as canonical `./icons/<set>/<slug>.svg` files for image consumers. See [ICONS.md](ICONS.md). Version 0.21.1 accepts status-page `routes` straight from a sitemap: long titles are shortened for the "Did you mean" line and unusable entries are dropped instead of failing the render. Version 0.21.0 replaces the 404 and route-error pages with one shared status page: the product's main action, a "Did you mean" link to the closest known page, at most three next links with one-line descriptions, an optional line for AI agents, and a glyph drawn as dots that gather, move away from the pointer, and settle. `RouteNotFoundPage`, `RouteErrorPage`, and `GlobalErrorDocument` render it; `renderStatusPageHtml` and `attachStatusPage` bring the same page to static sites; `status-page.css` ships in `styles.css` and `compiler-foundation.css`. The default copy changes to "We can’t find that page". See [STATUS_PAGES.md](STATUS_PAGES.md). Version 0.20.0 gives `ThemeMenuButton` the Lantern material: under `data-hraness-material="lantern"` its trigger is raised at rest and inset while pressed, and its menu uses the material plane, lift and warm selection, with no new props. Sites can delete their local Lantern CSS for the appearance menu. It also adds `formatRelativeTime` at the package root and a hydration-safe `RelativeTime` component in `@hraness/design-kit/react`. Version 0.19.0 redraws related-product cards as the hraness.com project cards: each shows the product's mark, its name, and its one-line `role` at reading size, and no longer renders the `relationship` sentence (the prop stays accepted and is deprecated). `MarketingRelatedProduct` and the static `ArticleRelatedLink` take a `mark`, and every `@hraness/design-kit/portfolio` product and `relatedFor()` item now carries its portfolio mark as an inert `data:image/svg+xml` URL. Related-tier and proof headings move to the new `--hraness-marketing-h3-size` token, so the editorial display face never renders below 1.75rem. `typography.css` gains per-level heading tokens (`--hraness-type-h1-font` through `--hraness-type-h4-font`, the matching `-weight` tokens, `--hraness-type-subheading-font`, and `--hraness-type-display-min`). h3 and h4 in `.hraness-prose` and publication articles now use the text face, and the h2 floor rises to 1.75rem. Version 0.18.3 adds the Sponge and Wordcell runtime relations to Oh to the `@hraness/design-kit/portfolio` snapshot, so related-product cards on all three sites can link them. Version 0.18.2 refreshes the `@hraness/design-kit/portfolio` snapshot from the registry: the public ghostget.com entry, updated Gobstopper and xcb naming and descriptions, and the current sibling-product relations for related-product cards. Version 0.18.1 adds the Perplexity mark and a dependency-free `@hraness/design-kit/provider-marks` leaf entry (`providerMark`, `providerMarks`, `providerMarkFallback`, `providerMarkGlyphDataUri`, `providerMarkArtDataUri`, `providerMarkOnAccent`, `providerMarkMonogram`) so packages such as `@hraness/ui` can consume the registry without pulling the marketing surface. Version 0.18.0 adds the shared provider-mark registry: `providerMarks`, `providerMark()` alias resolution, `ProviderMark`/`ProviderMarkChip` accent-tinted tile components on both React entry points, vendored agent and vendor artwork from LobeHub icons 1.95.1 plus documented Crush and Aider marks, monogram fallbacks for uncovered names, and data-URI helpers for CSS-mask consumers. See `vendor/provider-marks/UPSTREAM.md` for asset provenance. Version 0.17.2 carries the canonical portfolio messaging record per product (`names`, `category`, `tagline`, `short`, `meta`, `medium`, `long`, and hero copy) in the `/portfolio` snapshot. Version 0.17.1 lets Next.js apps that compile dependencies with Babel build the article layer: its link check no longer uses a Unicode property escape that Babel cannot rewrite, and it rejects the same control characters and whitespace as before. Version 0.17.0 adds the article layer: server-safe `MarketingArticle`, byline, provenance, sources, callout, related-product, and index components, a matching static HTML renderer for sites without React, long-form article styles in `plain-publication.css`, and the `ArticleAdmission` rubric with `assertArticleAdmissions()`. It also adds `@hraness/design-kit/portfolio`, a snapshot of public product names, one-liners, links, and relations for related-product cards and "How X uses Y" posts. See [ARTICLE_COPY.md](ARTICLE_COPY.md). Version 0.16.4 keeps native appearance-menu labels usable inside keyboard-focusable page landmarks, including mouse and touch selection. Version 0.16.3 keeps decorative hero backgrounds hidden in forced colors and reduced transparency when other packages load their styles afterward. Version 0.16.2 preserves palette hues in translucent headers, material surfaces, and decorative highlights. Version 0.16.1 keeps plain reading pages and nested compiled surfaces in their selected palette, including system appearance without JavaScript. Version 0.16.0 adds a shared bounded hero light, product-owned backdrop slots, five Lantern patterns, palette-derived soft surfaces, and responsive typography across marketing and reading layouts. Static sites can use the palette bridge for system appearance before JavaScript. See [HERO_FIELDS.md](HERO_FIELDS.md), [LANTERN_MATERIAL.md](LANTERN_MATERIAL.md), and [MARKETING_PRESET.md](MARKETING_PRESET.md). Version 0.15.0 lets `MarketingRelated` present labeled tiers of sibling products: a `groups` collection renders each tier under its own heading with an accessible card-row label, while the flat `items` shape stays available for a single group. Version 0.14.0 adds `MarketingRelated`, a collection section that presents sibling products as linked cards, each framed by its relationship to the featured product. Version 0.13.0 publishes `--hraness-sticky-offset` from sticky marketing chrome, gives `MarketingMain` and the next sticky sibling a clearance contract, stretches marketing card rows to the tallest item with a reserved two-line meta block, and clips per-card art wells so a logo surface cannot paint through the gutter. Version 0.12.0 replaces pointer-driven gradient rotation with a steady material and a moving light: the spectrum and its 115deg direction stay fixed while `--hraness-foil-x`/`--hraness-foil-y` highlights travel across each lockup, and marketing footers can opt into the same icon-plus-wordmark foil as the site header with `brandMark`. Version 0.11.1 preserves visible metallic marks when another package repeats a generic hidden atom in a later CSS layer. React consumers load `components.css` or `styles.css`; the raw marketing entry supports authored HTML hooks. Version 0.11 adds server-rendered `FoilMark` artwork and metallic text with subtle rainbow reflections, including a shared header mark seam and original-artwork fallbacks. Version 0.10.1 adds conservative server syntax defaults, includes their styles in the narrow marketing entry, and pins the icon dependency to preserve fresh Linux installs. Version 0.10 adds the shared foil contract: `.hraness-foil` surfaces and `.hraness-foil-text` wordmarks render a pointer-following metallic spectrum from the `--hraness-foil-*` custom properties, applied by default to marketing header brands and primary actions. The `attachFoil` browser export drives the bounded `x`/`y`/`angle` inputs with damped easing, reduced-motion and forced-color fallbacks, and no style injection; the same spectrum feeds `@hraness/site-footer` signup controls. Dark appearances use a deeper palette so the sheen stays visible. Version 0.8 removes Jelly's optional API, stylesheet, vendor runtime and theme-provider side effect. Migrate direct Jelly surfaces to native shared primitives before upgrading. Lantern now uses softer directional depth and shaded faces; the marketing preset adds individually shaded static cells, theme-aware terminal colors and window chrome. Code blocks retain source lines and follow the active palette. Paper preferences, semantic palettes, and compiler identity stay stable. Compiler adopters must regenerate their finalized stylesheet with the new package manifest.
989
+ The stable dependency pair for this release is `@hraness/ui` `v0.5.17` with `@hraness/design-kit` `v0.41.1`. Version 0.31.0 keeps the `limits` beat and beats marked `social: false` out of the social kit and adds `socialPost` for social wording that stands without a caveat. Version 0.30.3 refreshes the portfolio snapshot so related-product cards use each product's own spelling, such as GhostGet and TextButler. Version 0.30.2 keeps the narrow and stacked install-tab layout when another package compiles the same atoms into a later cascade layer. Version 0.30.1 keeps every PlatformInstall tab name whole in columns down to 200px by stacking each mark above its name, using a container query on the component. Version 0.30.0 adds `site-shell.css`, which keeps short-page footers at the viewport bottom. Version 0.29.3 preserves readable selected install tabs in forced colors. Version 0.29.2 keeps all three PlatformInstall tabs visible at 320 to 360px and draws each platform mark once per component. Version 0.29.1 keeps marketing action labels readable in forced colors. Version 0.29.0 adds `PlatformInstall`, one install block for every CLI site: a tab per operating system with its mark, the install command with a Copy button that announces the result, optional alternative commands such as npm or Homebrew, and a note for platforms without a native build. After hydration it selects the visitor's operating system; without JavaScript every command shows. It also adds `PlatformIcon` (Apple, Tux, and Windows marks in `currentColor`) and a `PlatformBadges` "Runs on" row, plus `platformLabel`, `platformMark`, `detectPlatform`, and `matchDetectedPlatform` at the package root. See [Install commands for each platform](#install-commands-for-each-platform). No existing export changes. Version 0.28.0 adds the launch kit. `@hraness/design-kit/mockups` draws labelled illustrations of chat, feeds, inboxes, articles, terminals, browsers, desktop windows, menu bars, and phones in server-safe plain React with no StyleX or React Aria, styled by `@hraness/design-kit/mockups.css`; each renders as one image with a text description and no headings. `@hraness/design-kit/mockups/client` adds `ModeShowcase`, `FitToWidth`, and `StepThrough`. `@hraness/design-kit/launch`, with no React, holds the `LaunchBeat`, `LaunchFacts`, and `SocialKit` shapes with `resolveLaunchBeats`, `buildSocialKit`, and `assertLaunchKit`. `@hraness/design-kit/testing` gives product repositories `blogConformance`, `renderMatrix`, `assertNoHeadings`, `assertRoleImgWithLabel`, and `assertFakeHandles`. The React entries add `ArticleFigure`, `ArticleVideo` with `articleVideoJsonLd`, `ArticleTable`, `ArticleBarChart`, `ComparisonTable`, `LaunchBeats`, and `SocialKitPanel`, and `MarketingProofFrame` takes `chrome` (`window`, `browser` with `url`, or `terminal`). [ARTICLE_COPY.md](ARTICLE_COPY.md) now writes "Introducing a product" as beats; the admission rules are unchanged. No existing export changes. Version 0.27.0 adds explicit Rust, TOML, YAML, Lean, and TLA+ code highlighting, including nested comments and multiline strings. The existing highlighter API and stylesheet remain the shared entry points; unsupported languages still render as escaped text. Version 0.26.0 adds `MarketingNotice` and the raw `.hraness-marketing-notice` class: one status or alert line (`info`, `success`, or `error`) that sits on the content edge of the page column instead of spanning the window. Errors are announced as alerts and other tones as status. Signed-in account pages that render inside `MarketingSiteHeader` should compose `MarketingMain`, `MarketingNotice`, `MarketingStatStrip`, and `MarketingSection` so every block shares the header's measure and gutter, rather than hand-rolled full-bleed banners and nested cards. Version 0.25.0 moves bordered foil surfaces off the spectrum: `.hraness-foil` and `[data-emphasis="primary"]` actions keep their flat surface fill under one theme-aware monochrome edge — black on light, white on dark, overridable through the new `--hraness-foil-edge` token — while the metallic spectrum stays on wordmarks and marks. The foil material contract advances to version 3: `surfaceImage` and `surfaceBackgroundClip` are replaced by `surfaceFill`, `edge`, `edgeDark`, and `edgeColor`. Reinstall any vendored marketing snapshot from the 0.25.0 commit. Version 0.24.0 joins a marketing footer directly followed by the shared `@hraness/site-footer` network footer into one band: the product row's bottom space collapses to a compact gap and the network row's content follows the marketing measure and gutter through `--hraness-site-footer-measure`, so product links and the organization row share one column instead of reading as two stacked bars. Mount the network footer directly after `MarketingSiteFooter`; no prop or markup change is needed inside either landmark. Version 0.23.0 moves marketing pages to the Quiet direction described in [DESIGN.md](DESIGN.md). `ProductHero` no longer renders a backdrop, `HeroBackdrop` renders nothing, and `attachHeroLight` is an inert disposer; their names and props stay so existing code compiles and are marked deprecated. The `cells`, `weave`, `contour`, and `mesh` patterns render as `none`, and marketing fields and Lantern walls paint the flat palette background. Both marketing presets use Nebula Sans for display headings (editorial at weight 550); Instrument Serif stays vendored for explicit opt-in only. Hero eyebrows are plain labels, the accent band loses its grid, and cards and header chrome use hairline edges instead of lifted shadows. On phones `MarketingSiteHeader` keeps the brand, primary action, and appearance menu on one row and moves the links to a second row that scrolls sideways, with 44px targets. To migrate, delete `backdrop` artwork, `HeroBackdrop`, `attachHeroLight`, pattern values, and product CSS that recreated textures or serif headings, then reinstall any vendored marketing snapshot from the 0.23.0 commit. Version 0.22.2 restores the canonical roughday mark — the rain-cloud artwork pinned by the portfolio registry — after the mark slot briefly carried a stray illustration. Version 0.22.1 completes the icon library with the roughday inline chip family (65 admitted assets, no pending members). Version 0.22.0 adds the `./icons` surface: 62 vetted single-ink assets across ten sets — a shared illustration family, product illustration families, and the product marks, each admitted through a measured gate (single ink, bounded aspect, coverage, stroke, paths, bytes) and per-set family coherence, distributed as a typed registry module (`hranessIcons`, `hranessIcon`, `hranessIconMarkup`, `hranessIconsForSet`) and as canonical `./icons/<set>/<slug>.svg` files for image consumers. See [ICONS.md](ICONS.md). Version 0.21.1 accepts status-page `routes` straight from a sitemap: long titles are shortened for the "Did you mean" line and unusable entries are dropped instead of failing the render. Version 0.21.0 replaces the 404 and route-error pages with one shared status page: the product's main action, a "Did you mean" link to the closest known page, at most three next links with one-line descriptions, an optional line for AI agents, and a glyph drawn as dots that gather, move away from the pointer, and settle. `RouteNotFoundPage`, `RouteErrorPage`, and `GlobalErrorDocument` render it; `renderStatusPageHtml` and `attachStatusPage` bring the same page to static sites; `status-page.css` ships in `styles.css` and `compiler-foundation.css`. The default copy changes to "We can’t find that page". See [STATUS_PAGES.md](STATUS_PAGES.md). Version 0.20.0 gives `ThemeMenuButton` the Lantern material: under `data-hraness-material="lantern"` its trigger is raised at rest and inset while pressed, and its menu uses the material plane, lift and warm selection, with no new props. Sites can delete their local Lantern CSS for the appearance menu. It also adds `formatRelativeTime` at the package root and a hydration-safe `RelativeTime` component in `@hraness/design-kit/react`. Version 0.19.0 redraws related-product cards as the hraness.com project cards: each shows the product's mark, its name, and its one-line `role` at reading size, and no longer renders the `relationship` sentence (the prop stays accepted and is deprecated). `MarketingRelatedProduct` and the static `ArticleRelatedLink` take a `mark`, and every `@hraness/design-kit/portfolio` product and `relatedFor()` item now carries its portfolio mark as an inert `data:image/svg+xml` URL. Related-tier and proof headings move to the new `--hraness-marketing-h3-size` token, so the editorial display face never renders below 1.75rem. `typography.css` gains per-level heading tokens (`--hraness-type-h1-font` through `--hraness-type-h4-font`, the matching `-weight` tokens, `--hraness-type-subheading-font`, and `--hraness-type-display-min`). h3 and h4 in `.hraness-prose` and publication articles now use the text face, and the h2 floor rises to 1.75rem. Version 0.18.3 adds the Sponge and Wordcell runtime relations to Oh to the `@hraness/design-kit/portfolio` snapshot, so related-product cards on all three sites can link them. Version 0.18.2 refreshes the `@hraness/design-kit/portfolio` snapshot from the registry: the public ghostget.com entry, updated Gobstopper and xcb naming and descriptions, and the current sibling-product relations for related-product cards. Version 0.18.1 adds the Perplexity mark and a dependency-free `@hraness/design-kit/provider-marks` leaf entry (`providerMark`, `providerMarks`, `providerMarkFallback`, `providerMarkGlyphDataUri`, `providerMarkArtDataUri`, `providerMarkOnAccent`, `providerMarkMonogram`) so packages such as `@hraness/ui` can consume the registry without pulling the marketing surface. Version 0.18.0 adds the shared provider-mark registry: `providerMarks`, `providerMark()` alias resolution, `ProviderMark`/`ProviderMarkChip` accent-tinted tile components on both React entry points, vendored agent and vendor artwork from LobeHub icons 1.95.1 plus documented Crush and Aider marks, monogram fallbacks for uncovered names, and data-URI helpers for CSS-mask consumers. See `vendor/provider-marks/UPSTREAM.md` for asset provenance. Version 0.17.2 carries the canonical portfolio messaging record per product (`names`, `category`, `tagline`, `short`, `meta`, `medium`, `long`, and hero copy) in the `/portfolio` snapshot. Version 0.17.1 lets Next.js apps that compile dependencies with Babel build the article layer: its link check no longer uses a Unicode property escape that Babel cannot rewrite, and it rejects the same control characters and whitespace as before. Version 0.17.0 adds the article layer: server-safe `MarketingArticle`, byline, provenance, sources, callout, related-product, and index components, a matching static HTML renderer for sites without React, long-form article styles in `plain-publication.css`, and the `ArticleAdmission` rubric with `assertArticleAdmissions()`. It also adds `@hraness/design-kit/portfolio`, a snapshot of public product names, one-liners, links, and relations for related-product cards and "How X uses Y" posts. See [ARTICLE_COPY.md](ARTICLE_COPY.md). Version 0.16.4 keeps native appearance-menu labels usable inside keyboard-focusable page landmarks, including mouse and touch selection. Version 0.16.3 keeps decorative hero backgrounds hidden in forced colors and reduced transparency when other packages load their styles afterward. Version 0.16.2 preserves palette hues in translucent headers, material surfaces, and decorative highlights. Version 0.16.1 keeps plain reading pages and nested compiled surfaces in their selected palette, including system appearance without JavaScript. Version 0.16.0 adds a shared bounded hero light, product-owned backdrop slots, five Lantern patterns, palette-derived soft surfaces, and responsive typography across marketing and reading layouts. Static sites can use the palette bridge for system appearance before JavaScript. See [HERO_FIELDS.md](HERO_FIELDS.md), [LANTERN_MATERIAL.md](LANTERN_MATERIAL.md), and [MARKETING_PRESET.md](MARKETING_PRESET.md). Version 0.15.0 lets `MarketingRelated` present labeled tiers of sibling products: a `groups` collection renders each tier under its own heading with an accessible card-row label, while the flat `items` shape stays available for a single group. Version 0.14.0 adds `MarketingRelated`, a collection section that presents sibling products as linked cards, each framed by its relationship to the featured product. Version 0.13.0 publishes `--hraness-sticky-offset` from sticky marketing chrome, gives `MarketingMain` and the next sticky sibling a clearance contract, stretches marketing card rows to the tallest item with a reserved two-line meta block, and clips per-card art wells so a logo surface cannot paint through the gutter. Version 0.12.0 replaces pointer-driven gradient rotation with a steady material and a moving light: the spectrum and its 115deg direction stay fixed while `--hraness-foil-x`/`--hraness-foil-y` highlights travel across each lockup, and marketing footers can opt into the same icon-plus-wordmark foil as the site header with `brandMark`. Version 0.11.1 preserves visible metallic marks when another package repeats a generic hidden atom in a later CSS layer. React consumers load `components.css` or `styles.css`; the raw marketing entry supports authored HTML hooks. Version 0.11 adds server-rendered `FoilMark` artwork and metallic text with subtle rainbow reflections, including a shared header mark seam and original-artwork fallbacks. Version 0.10.1 adds conservative server syntax defaults, includes their styles in the narrow marketing entry, and pins the icon dependency to preserve fresh Linux installs. Version 0.10 adds the shared foil contract: `.hraness-foil` surfaces and `.hraness-foil-text` wordmarks render a pointer-following metallic spectrum from the `--hraness-foil-*` custom properties, applied by default to marketing header brands and primary actions. The `attachFoil` browser export drives the bounded `x`/`y`/`angle` inputs with damped easing, reduced-motion and forced-color fallbacks, and no style injection; the same spectrum feeds `@hraness/site-footer` signup controls. Dark appearances use a deeper palette so the sheen stays visible. Version 0.8 removes Jelly's optional API, stylesheet, vendor runtime and theme-provider side effect. Migrate direct Jelly surfaces to native shared primitives before upgrading. Lantern now uses softer directional depth and shaded faces; the marketing preset adds individually shaded static cells, theme-aware terminal colors and window chrome. Code blocks retain source lines and follow the active palette. Paper preferences, semantic palettes, and compiler identity stay stable. Compiler adopters must regenerate their finalized stylesheet with the new package manifest.
957
990
 
958
991
  The complete check runs linting, typechecking, production builds, an installed-package smoke test, deterministic examples, property tests, server rendering, vendor-integrity checks, and headless Chromium regressions. The browser gate verifies responsive shell ownership, extracted AnimatedRailStage, Fader, layout-surface, and playback-transport delivery, reduced-motion stage fallback, Fader keyboard and focus behavior, forced-color behavior, keyboard-operable appearance, browser-chrome synchronization across opposing device and saved preferences, global-error static metadata and runtime lifecycle, accessible title and copy, deterministic procedural layers, viewport containment, and the absence of the excluded canvas effect. Provision the pinned Chromium with `bun run browser:install`. An explicit `CHROMIUM_EXECUTABLE_PATH` must resolve to a provisioned Chrome for Testing; the browser gate rejects installed auto-updating Chrome.
959
992
 
@@ -1269,7 +1269,7 @@ var marketingStyles = {
1269
1269
  k1xSpc: "x78zum5",
1270
1270
  kkeX5w: "x6s0dn4",
1271
1271
  kOIVth: "x8233eu",
1272
- kmVPX3: "x86o7ao",
1272
+ kmVPX3: "xrqs5gp",
1273
1273
  kb5WsR: "x1drtmal xhobzj1",
1274
1274
  kTJQHc: "xs301gt xwaqzdf",
1275
1275
  ke4D0g: "xothggy x1j9yjdw",
@@ -2214,10 +2214,10 @@ var marketingStyles = {
2214
2214
  $$css: true
2215
2215
  },
2216
2216
  interface: {
2217
- k1xSpc: "xrvj5dj",
2217
+ k1xSpc: "x78zum5",
2218
+ kvQiKF: "xdt5ytf",
2218
2219
  kdYMnH: "xesnm00",
2219
2220
  kVQ08L: "x1ljpu7r",
2220
- kNk6WL: "x10ukxgv",
2221
2221
  kOIVth: "x13z6uf9",
2222
2222
  kmVPX3: "x1nn0urv",
2223
2223
  k99D8V: "x17p5ghk x18z9243",
@@ -2285,6 +2285,21 @@ var marketingStyles = {
2285
2285
  kN5DiO: "x1evy7pa",
2286
2286
  $$css: true
2287
2287
  },
2288
+ interface__action: {
2289
+ kAiAap: "x1n5yk0f",
2290
+ kLh5Sq: "x1qzg9v8",
2291
+ kMCLAl: "xp4054r",
2292
+ $$css: true
2293
+ },
2294
+ interface__link: {
2295
+ kMwMTN: "xs87ocq x16tyrwk x1eyr600 x1ljrylj",
2296
+ kXaGww: "xujl8zx",
2297
+ kCBxTS: "xi2nhp4",
2298
+ kRHfhz: "x4k6xgu x9ojkr9 x1e7jyuc",
2299
+ kKoZWP: "xyi4chj",
2300
+ k1PBYE: "x5hzr90",
2301
+ $$css: true
2302
+ },
2288
2303
  trust_item__label: {
2289
2304
  kogj98: "x1ghz6dp",
2290
2305
  kLh5Sq: "x1ksoetq",
@@ -2676,6 +2691,7 @@ var marketingStyles = {
2676
2691
  kGmCso: "x1qughib",
2677
2692
  kOIVth: "x8fetqu",
2678
2693
  kF3gjK: "xgepmj6",
2694
+ kJVvJu: "x18wjirm",
2679
2695
  kMwMTN: "xtylnni",
2680
2696
  kkrTdU: "x1ypdohk",
2681
2697
  kLh5Sq: "x1ksoetq",
@@ -2688,12 +2704,16 @@ var marketingStyles = {
2688
2704
  kNmtQP: "x1h4a8v0",
2689
2705
  kF3crb: "x17thtq2",
2690
2706
  kJ3DBm: "x1ioofie",
2691
- kLigFv: "x1bz48vb",
2707
+ kLZV2q: "x78hkw1 x4oqjru",
2708
+ kVDYEw: "xjocvvi",
2709
+ k7kefo: "x15fj410",
2710
+ kLigFv: "xba5a1s",
2692
2711
  $$css: true
2693
2712
  },
2694
2713
  question__answer: {
2695
2714
  k2kXS: "xjq529q",
2696
2715
  kF3gjK: "xs0puwk",
2716
+ kJVvJu: "x18wjirm",
2697
2717
  kMwMTN: "xs87ocq",
2698
2718
  kN5DiO: "x1dbl2gt",
2699
2719
  $$css: true
@@ -3654,6 +3674,12 @@ var recipes = {
3654
3674
  "hraness-marketing-interface__summary": {
3655
3675
  default: marketingStyles.interface__summary
3656
3676
  },
3677
+ "hraness-marketing-interface__action": {
3678
+ default: marketingStyles.interface__action
3679
+ },
3680
+ "hraness-marketing-interface__link": {
3681
+ default: marketingStyles.interface__link
3682
+ },
3657
3683
  "hraness-marketing-trust-item__label": {
3658
3684
  default: marketingStyles.trust_item__label
3659
3685
  },
@@ -3921,14 +3947,18 @@ function MarketingPage({
3921
3947
  children,
3922
3948
  className,
3923
3949
  id,
3950
+ landscape,
3924
3951
  preset,
3925
3952
  pattern
3926
3953
  }) {
3927
3954
  if (preset !== undefined && preset !== "editorial" && preset !== "minimal")
3928
3955
  throw new RangeError("Unknown marketing preset.");
3956
+ if (landscape !== undefined && landscape !== "page" && landscape !== "contained" && landscape !== "off")
3957
+ throw new RangeError("Unknown landscape host.");
3929
3958
  assertMarketingPattern(pattern);
3930
3959
  return /* @__PURE__ */ jsx3("div", {
3931
3960
  className: marketingClassName("hraness-marketing-page", className),
3961
+ "data-hraness-landscape": landscape,
3932
3962
  "data-hraness-marketing": "page",
3933
3963
  "data-hraness-marketing-preset": preset,
3934
3964
  "data-hraness-pattern": pattern,
@@ -4466,8 +4496,8 @@ function MarketingProofFrame({
4466
4496
  throw new RangeError('Proof frame url needs chrome="browser".');
4467
4497
  const bar = chrome ?? (title === undefined ? undefined : "window");
4468
4498
  const label = bar === "browser" ? url === undefined ? title : marketingProofFrameAddress(url) : title;
4469
- if (bar !== undefined && (label === undefined || label.trim() === "")) {
4470
- throw new RangeError(`Proof frame chrome=${bar} needs ${bar === "browser" ? "a url or title" : "a title"}.`);
4499
+ if (bar === "browser" && (label === undefined || label.trim() === "")) {
4500
+ throw new RangeError("Proof frame chrome=browser needs a url or title.");
4471
4501
  }
4472
4502
  return /* @__PURE__ */ jsxs3("figure", {
4473
4503
  className: marketingClassName("hraness-marketing-proof-frame", className),
@@ -4495,7 +4525,7 @@ function MarketingProofFrame({
4495
4525
  bar === "browser" ? /* @__PURE__ */ jsx3("span", {
4496
4526
  className: marketingClassName("hraness-marketing-proof-frame__address"),
4497
4527
  children: label
4498
- }) : /* @__PURE__ */ jsx3("span", {
4528
+ }) : label === undefined || label.trim() === "" ? null : /* @__PURE__ */ jsx3("span", {
4499
4529
  className: marketingClassName("hraness-marketing-proof-frame__title", undefined, bar === "terminal" ? "terminal" : "default"),
4500
4530
  children: label
4501
4531
  })
@@ -4873,7 +4903,16 @@ function MarketingInterfaceGrid({
4873
4903
  className: marketingClassName("hraness-marketing-interface__summary"),
4874
4904
  children: entry.summary
4875
4905
  }),
4876
- entry.example
4906
+ entry.example,
4907
+ entry.link === undefined ? null : /* @__PURE__ */ jsx3("p", {
4908
+ className: marketingClassName("hraness-marketing-interface__action"),
4909
+ children: /* @__PURE__ */ jsx3("a", {
4910
+ className: marketingClassName("hraness-marketing-interface__link"),
4911
+ "data-hraness-marketing": "interfaces",
4912
+ href: entry.link.href,
4913
+ children: entry.link.label
4914
+ })
4915
+ })
4877
4916
  ]
4878
4917
  }, entry.label))
4879
4918
  })
@@ -90,7 +90,7 @@ import {
90
90
  marketingProofFrameAddress,
91
91
  proceduralBackdropVariants,
92
92
  proceduralRecipeVersion
93
- } from "../chunk-s96ppgkp.js";
93
+ } from "../chunk-kgrbekna.js";
94
94
  import {
95
95
  SyntaxCode
96
96
  } from "../chunk-6ts4955n.js";
@@ -6872,10 +6872,18 @@ Run the job, then show me its log.`,
6872
6872
  summary: "Run a named job.",
6873
6873
  example: /* @__PURE__ */ jsx17(MarketingCodeBlock, {
6874
6874
  code: "relay run job-01"
6875
- })
6875
+ }),
6876
+ link: {
6877
+ href: "#gallery-install",
6878
+ label: "Read the CLI guide"
6879
+ }
6876
6880
  }, {
6877
6881
  label: "SDK",
6878
- summary: "Use typed application code."
6882
+ summary: "Use typed application code.",
6883
+ link: {
6884
+ href: "#gallery-install",
6885
+ label: "Read the SDK guide"
6886
+ }
6879
6887
  }]
6880
6888
  }),
6881
6889
  /* @__PURE__ */ jsx17(MarketingCardRow, {
@@ -7922,6 +7930,38 @@ Run the job, then show me its log.`,
7922
7930
  ]
7923
7931
  })
7924
7932
  ]
7933
+ }),
7934
+ /* @__PURE__ */ jsxs15("div", {
7935
+ className: "design-gallery__landscape",
7936
+ "data-hraness-landscape": "contained",
7937
+ style: {
7938
+ "--hraness-landscape-image": `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Crect width='400' height='300'/%3E%3Cg fill='none' stroke='white' stroke-width='1.5'%3E%3Cpath d='M0 240 L40 190 L70 215 L110 150 L150 205 L170 185'/%3E%3Cpath d='M230 185 L260 150 L300 200 L340 140 L370 180 L400 160'/%3E%3Cpath d='M20 270 C60 250 100 262 150 250'/%3E%3Cpath d='M250 252 C300 262 340 248 390 262'/%3E%3Ccircle cx='340' cy='60' r='16'/%3E%3C/g%3E%3C/svg%3E")`
7939
+ },
7940
+ children: [
7941
+ /* @__PURE__ */ jsxs15("div", {
7942
+ className: "design-gallery__landscape-copy",
7943
+ children: [
7944
+ /* @__PURE__ */ jsx17("h3", {
7945
+ children: "Product landscape"
7946
+ }),
7947
+ /* @__PURE__ */ jsx17("p", {
7948
+ children: "One product drawing, tinted from the palette and tiled down the page. Code and tables stay solid with rounded edges; small cards and callouts frost over it."
7949
+ })
7950
+ ]
7951
+ }),
7952
+ /* @__PURE__ */ jsx17("pre", {
7953
+ className: "design-gallery__landscape-code",
7954
+ "data-hraness-landscape-surface": "solid",
7955
+ children: /* @__PURE__ */ jsx17("code", {
7956
+ children: "relay run job-01"
7957
+ })
7958
+ }),
7959
+ /* @__PURE__ */ jsx17("p", {
7960
+ className: "design-gallery__landscape-note",
7961
+ "data-hraness-landscape-surface": "glass",
7962
+ children: "The log is written next to the job."
7963
+ })
7964
+ ]
7925
7965
  })
7926
7966
  ]
7927
7967
  }),
@@ -69,7 +69,7 @@ import {
69
69
  marketingProofFrameAddress,
70
70
  proceduralBackdropVariants,
71
71
  proceduralRecipeVersion
72
- } from "../chunk-s96ppgkp.js";
72
+ } from "../chunk-kgrbekna.js";
73
73
  import {
74
74
  SyntaxCode
75
75
  } from "../chunk-6ts4955n.js";