@bitbaum/sitekit 0.4.0 → 0.4.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/README.md CHANGED
@@ -154,3 +154,9 @@ Tests import the package by **name** (`@bitbaum/sitekit`, `@bitbaum/sitekit/reac
154
154
  Part of **[bitbaum](https://bitbaum.orangecat.ch)** — AI-native products on open
155
155
  infrastructure, built in Zürich. Every package here lists the apps that use it:
156
156
  **[which apps use sitekit](https://bitbaum.orangecat.ch/packages/#sitekit)**.
157
+
158
+ Application footers can pass `groups: [{ label, links: [{ href, label }] }]` for
159
+ semantic navigation groups. Existing flat `links` remain supported. Consumers
160
+ can configure `--sk-header-height`, `--sk-mobile-header-height`,
161
+ `--sk-display-weight`, `--sk-display-leading`, `--sk-display-tracking` and
162
+ `--sk-footer-gap` through their theme adapter, without replacing shared markup.
@@ -17,13 +17,21 @@ interface Props {
17
17
  menuLabel?: string;
18
18
  }
19
19
  export declare function SiteMasthead({ chrome, navItems, currentPath, Link, appearance, brand, actions, mainId, skipLabel, navLabel, menuLabel, }: Props): import("react").JSX.Element;
20
- export declare function SiteFooter({ chrome, appearance, links, Link, label, extra, }: {
20
+ export declare function SiteFooter({ chrome, appearance, links, groups, Link, label, extra, }: {
21
21
  chrome: SiteChromeSpec;
22
22
  appearance?: 'application';
23
23
  links?: Array<{
24
24
  href: string;
25
25
  label: string;
26
26
  }>;
27
+ /** Optional semantic link groups; flat links remain supported. */
28
+ groups?: Array<{
29
+ label: string;
30
+ links: Array<{
31
+ href: string;
32
+ label: string;
33
+ }>;
34
+ }>;
27
35
  Link?: LinkLike;
28
36
  label?: string;
29
37
  extra?: ReactNode;
@@ -18,8 +18,8 @@ export function SiteMasthead({ chrome, navItems, currentPath, Link = DefaultLink
18
18
  return (_jsxs(_Fragment, { children: [mainId && (_jsx("a", { className: "sk-skip", href: '#' + mainId, children: skipLabel })), _jsx("header", { className: "sk-masthead", children: _jsxs("div", { className: "sk-shell-frame sk-masthead-row", children: [_jsx(Link, { href: "/", className: "sk-brand", children: brand ?? chrome.name }), _jsx(SiteNav, { items: navItems, currentPath: currentPath, Link: Link, appearance: "application", label: navLabel, menuLabel: menuLabel }), actions && _jsx("div", { className: "sk-account-actions", children: actions })] }) })] }));
19
19
  return (_jsx("header", { className: "sticky top-0 z-30 border-b border-subtle bg-surface-page/85 backdrop-blur", children: _jsx("div", { className: "mx-auto max-w-shell px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-6 py-2", children: [_jsx(Link, { href: href(), className: "inline-flex min-h-11 shrink-0 items-center rounded focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent", children: _jsx("span", { className: "font-heading text-lg font-semibold tracking-display text-fg-primary", children: chrome.name }) }), _jsx(SiteNav, { items: navItems, currentPath: currentPath, Link: Link })] }) }) }));
20
20
  }
21
- export function SiteFooter({ chrome, appearance, links = [], Link = DefaultLink, label = 'Footer navigation', extra, }) {
21
+ export function SiteFooter({ chrome, appearance, links = [], groups, Link = DefaultLink, label = 'Footer navigation', extra, }) {
22
22
  if (appearance === 'application')
23
- return (_jsx("footer", { className: "sk-footer", children: _jsxs("div", { className: "sk-shell-frame", children: [_jsxs("div", { className: "sk-footer-top", children: [_jsxs("div", { children: [_jsx(Link, { href: "/", className: "sk-footer-brand", children: chrome.name }), _jsx("p", { children: chrome.footerNote })] }), _jsx("nav", { "aria-label": label, children: links.map((item) => (_jsx(Link, { href: item.href, children: item.label }, item.href))) })] }), _jsxs("div", { className: "sk-footer-bottom", children: [_jsxs("span", { children: ["\u00A9 ", new Date().getFullYear(), " ", chrome.name] }), extra] })] }) }));
23
+ return (_jsx("footer", { className: "sk-footer", children: _jsxs("div", { className: "sk-shell-frame", children: [_jsxs("div", { className: "sk-footer-top", children: [_jsxs("div", { children: [_jsx(Link, { href: "/", className: "sk-footer-brand", children: chrome.name }), _jsx("p", { children: chrome.footerNote })] }), groups ? (_jsx("nav", { "aria-label": label, className: "sk-footer-groups", children: groups.map((group) => (_jsxs("div", { className: "sk-footer-group", children: [_jsx("h2", { children: group.label }), group.links.map((item) => (_jsx(Link, { href: item.href, children: item.label }, item.href)))] }, group.label))) })) : (_jsx("nav", { "aria-label": label, children: links.map((item) => (_jsx(Link, { href: item.href, children: item.label }, item.href))) }))] }), _jsxs("div", { className: "sk-footer-bottom", children: [_jsxs("span", { children: ["\u00A9 ", new Date().getFullYear(), " ", chrome.name] }), extra] })] }) }));
24
24
  return (_jsx("footer", { className: "mt-24 border-t border-subtle", children: _jsxs("div", { className: "mx-auto max-w-shell px-4 py-12 sm:px-6 lg:px-8", children: [_jsx("p", { className: "max-w-prose text-sm leading-relaxed text-fg-secondary", children: chrome.footerNote }), _jsxs("div", { className: "mt-8 flex flex-col gap-2 border-t border-subtle pt-6 font-mono text-xs uppercase tracking-caps text-fg-muted sm:flex-row sm:items-center sm:justify-between", children: [chrome.host && _jsx("span", { children: chrome.host }), _jsxs("span", { className: "normal-case tracking-normal", children: ["\u00A9 ", chrome.name] })] })] }) }));
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitbaum/sitekit",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "A website as data: a closed union of section shapes validated at runtime, one set of React renderers, and per-field provenance so a generated site can prove it fabricated nothing.",
5
5
  "license": "MIT",
6
6
  "author": "Mao Nakamoto",
package/styles.css CHANGED
@@ -16,7 +16,7 @@
16
16
  border-bottom: 1px solid var(--sk-line, #d6d6d6);
17
17
  }
18
18
  .sk-masthead-row {
19
- min-height: 80px;
19
+ min-height: var(--sk-header-height, 80px);
20
20
  display: flex;
21
21
  align-items: center;
22
22
  gap: clamp(1rem, 2vw, 2rem);
@@ -127,7 +127,7 @@
127
127
  border-radius: var(--sk-radius, 0.5rem);
128
128
  }
129
129
  .sk-footer {
130
- margin-top: clamp(4rem, 8vw, 7rem);
130
+ margin-top: var(--sk-footer-gap, clamp(4rem, 8vw, 7rem));
131
131
  border-top: 1px solid var(--sk-line, #d6d6d6);
132
132
  background: var(--sk-bg, Canvas);
133
133
  padding-block: 3rem 1.5rem;
@@ -201,7 +201,7 @@
201
201
  }
202
202
  .sk-masthead-row {
203
203
  gap: 0.5rem;
204
- min-height: 72px;
204
+ min-height: var(--sk-mobile-header-height, 72px);
205
205
  }
206
206
  .sk-brand {
207
207
  margin-inline-end: auto;
@@ -234,9 +234,9 @@
234
234
  margin-block: 1rem 1.5rem;
235
235
  font-family: var(--sk-display, Georgia, serif);
236
236
  font-size: var(--sk-title-size, clamp(3rem, 6vw, 5rem));
237
- font-weight: 400;
238
- line-height: 1.05;
239
- letter-spacing: -0.045em;
237
+ font-weight: var(--sk-display-weight, 400);
238
+ line-height: var(--sk-display-leading, 1.05);
239
+ letter-spacing: var(--sk-display-tracking, -0.045em);
240
240
  text-wrap: balance;
241
241
  max-width: var(--sk-title-measure, 20ch);
242
242
  }
@@ -287,3 +287,22 @@
287
287
  grid-auto-flow: row;
288
288
  }
289
289
  }
290
+
291
+ .sk-footer nav.sk-footer-groups {
292
+ grid-template-columns: repeat(var(--sk-footer-columns, 3), minmax(0, 1fr));
293
+ gap: 1.5rem;
294
+ }
295
+ .sk-footer-group h2 {
296
+ margin: 0 0 0.75rem;
297
+ font: 600 0.75rem/1.5 var(--sk-font, system-ui, sans-serif);
298
+ color: var(--sk-fg, CanvasText);
299
+ }
300
+ .sk-footer-group a {
301
+ font-size: 0.8125rem;
302
+ }
303
+ @media (max-width: 600px) {
304
+ .sk-footer nav.sk-footer-groups {
305
+ grid-template-columns: repeat(2, minmax(0, 1fr));
306
+ gap: 1.5rem;
307
+ }
308
+ }