@the-portland-company/shell 0.70.0 → 0.71.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/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 0.71.1
2
+
3
+ Build line in the rail footer follows Specs/Left-Navigation §9 and Reference/UI-Platform Meta.
4
+ - Shown in production too, as `prod | <commit> | v<version>` over `date | author`.
5
+ - Two centered rows of plain mono text at 11px, with no chip and no leading or trailing pipes.
6
+
7
+ ## 0.71.0
8
+
9
+ Rail and top bar match the Specs/Left-Navigation Design.
10
+ - Org card logo band is 70px tall with 10px padding under it, and the org block sits 7px lower.
11
+ - Mode switcher buttons are compact and left-aligned on desktop.
12
+ - Top bar icon buttons have no border.
13
+ - The Dev notes button uses the notebook-pen icon.
14
+ - Footer links are centered and separated by a middle dot.
15
+
1
16
  ## 0.70.0 — 2026-10-06
2
17
 
3
18
  The top bar and left rail match Specs/Left-Navigation and Reference/UI-Platform.
@@ -305,7 +305,7 @@ function topBarIconButtonClass(tone = "default") {
305
305
  const toneClass = tone === "danger" || tone === "warning" ? "text-[color:var(--chrome-danger)] hover:text-[color:var(--chrome-danger)]" : "text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]";
306
306
  return [
307
307
  // `group/tbtip` powers the shared <TopBarTooltip> rendered inside the trigger.
308
- "group/tbtip relative flex items-center justify-center rounded-[var(--topbar-icon-button-radius,5px)] border border-[color:var(--line)] transition",
308
+ "group/tbtip relative flex items-center justify-center rounded-[var(--topbar-icon-button-radius,5px)] border border-transparent transition",
309
309
  "h-[var(--topbar-icon-button-size,34px)] w-[var(--topbar-icon-button-size,34px)]",
310
310
  toneClass
311
311
  ].join(" ");
@@ -2256,15 +2256,11 @@ function hasActiveChild(item, pathname, activeFn) {
2256
2256
  )
2257
2257
  );
2258
2258
  }
2259
- function envChipClasses(label) {
2260
- const l = label.toLowerCase();
2261
- if (l === "production" || l === "prod")
2262
- return "bg-[#fee2e2] text-[#ef4444]";
2263
- if (l === "staging" || l === "stage")
2264
- return "bg-[#ffedd5] text-[#f97316]";
2265
- if (l === "local" || l === "development" || l === "dev")
2266
- return "bg-[#dcfce7] text-[#22c55e]";
2267
- return "bg-[rgba(107,114,128,0.16)] text-[#6b7280]";
2259
+ function shortEnvLabel(label) {
2260
+ const l = label.trim().toLowerCase();
2261
+ if (l === "production") return "prod";
2262
+ if (l === "development") return "dev";
2263
+ return l;
2268
2264
  }
2269
2265
  var ORG_PILL_DEFAULT = "var(--color-accent)";
2270
2266
  var RailCollapsibleContext = react.createContext(false);
@@ -2469,7 +2465,7 @@ function NavSidebar({
2469
2465
  }
2470
2466
  ),
2471
2467
  org ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rc("max-md:flex max-md:justify-center"), children: [
2472
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mb-[7px] flex items-center justify-between ${rc("max-md:hidden")}`, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: NAV_EYEBROW_CLASS, children: "Organization" }) }),
2468
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mb-[7px] mt-[7px] flex items-center justify-between ${rc("max-md:hidden")}`, children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: NAV_EYEBROW_CLASS, children: "Organization" }) }),
2473
2469
  org.loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex w-full items-center gap-2.5 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 shadow-sm ${rc("max-md:w-auto max-md:border-0 max-md:bg-transparent max-md:p-0 max-md:shadow-none")}`, children: [
2474
2470
  /* @__PURE__ */ jsxRuntime.jsx(
2475
2471
  "span",
@@ -2495,7 +2491,7 @@ function NavSidebar({
2495
2491
  className: `flex w-full cursor-pointer list-none flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] [&::-webkit-details-marker]:hidden ${rc("max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent")}`,
2496
2492
  children: [
2497
2493
  /* @__PURE__ */ jsxRuntime.jsx(OrgIconMark, { org, logoSrc: orgLogoSrc }),
2498
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative flex h-[var(--sidebar-org-band-height,48px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc("max-md:hidden")}`, children: [
2494
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative flex h-[var(--sidebar-org-band-height,70px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc("max-md:hidden")}`, children: [
2499
2495
  orgLogoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: orgLogoSrc, alt: "", className: "max-h-full max-w-[132px] object-contain" }) : org.canUploadLogo ? /* @__PURE__ */ jsxRuntime.jsx(
2500
2496
  "a",
2501
2497
  {
@@ -2507,7 +2503,7 @@ function NavSidebar({
2507
2503
  ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-semibold text-neutral-800", children: org.name ?? "Organization" }),
2508
2504
  /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "absolute inset-x-0 bottom-0 h-[3px]", style: { backgroundImage: orgGradient } })
2509
2505
  ] }),
2510
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-2 ${rc("max-md:hidden")}`, children: [
2506
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-[10px] ${rc("max-md:hidden")}`, children: [
2511
2507
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
2512
2508
  /* @__PURE__ */ jsxRuntime.jsx(
2513
2509
  "span",
@@ -2597,7 +2593,7 @@ function NavSidebar({
2597
2593
  className: `flex w-full flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] ${rc("max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent")}`,
2598
2594
  children: [
2599
2595
  /* @__PURE__ */ jsxRuntime.jsx(OrgIconMark, { org, logoSrc: orgLogoSrc }),
2600
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative flex h-[var(--sidebar-org-band-height,48px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc("max-md:hidden")}`, children: [
2596
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `relative flex h-[var(--sidebar-org-band-height,70px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc("max-md:hidden")}`, children: [
2601
2597
  orgLogoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: orgLogoSrc, alt: "", className: "max-h-full max-w-[132px] object-contain" }) : org.canUploadLogo ? /* @__PURE__ */ jsxRuntime.jsx(
2602
2598
  "a",
2603
2599
  {
@@ -2609,7 +2605,7 @@ function NavSidebar({
2609
2605
  ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm font-semibold text-neutral-800", children: org.name ?? "Organization" }),
2610
2606
  /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "absolute inset-x-0 bottom-0 h-[3px]", style: { backgroundImage: orgGradient } })
2611
2607
  ] }),
2612
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-2 ${rc("max-md:hidden")}`, children: [
2608
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-[10px] ${rc("max-md:hidden")}`, children: [
2613
2609
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
2614
2610
  /* @__PURE__ */ jsxRuntime.jsx(
2615
2611
  "span",
@@ -2654,7 +2650,7 @@ function NavSidebar({
2654
2650
  },
2655
2651
  disabled: !available,
2656
2652
  className: [
2657
- "flex flex-1 items-center justify-center rounded-[5px] px-[9px] py-[6px] transition",
2653
+ `flex flex-none items-center justify-center rounded-[5px] px-[9px] py-[6px] transition ${rc("max-md:flex-1")}`,
2658
2654
  !available ? "cursor-not-allowed text-[color:var(--sidebar-text-muted,var(--muted))] opacity-35" : selected ? "bg-[color:var(--sidebar-mode-selected-bg,var(--mode-accent,var(--color-accent)))] text-[color:var(--mode-on-accent,white)]" : "text-[color:var(--sidebar-text-muted,var(--muted))] hover:bg-[#FFFFFF]/5 hover:text-[color:var(--sidebar-text,var(--foreground))]"
2659
2655
  ].join(" "),
2660
2656
  children: OptIcon ? /* @__PURE__ */ jsxRuntime.jsx(OptIcon, { size: 15, className: "shrink-0" }) : null
@@ -2744,50 +2740,37 @@ function NavSidebar({
2744
2740
  onSignOut: footer.onSignOut
2745
2741
  }
2746
2742
  ) : null,
2747
- footer.links && footer.links.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap items-center gap-[10px] text-[11px] leading-[1.2] ${footer.user ? "mt-3" : ""} ${rc("max-md:hidden")}`, children: footer.links.map((l) => /* @__PURE__ */ jsxRuntime.jsx(
2748
- "a",
2749
- {
2750
- href: safeHref(l.href),
2751
- className: "text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:text-[color:var(--sidebar-text,var(--foreground))] hover:underline",
2752
- children: l.label
2753
- },
2754
- l.label
2755
- )) }) : null,
2756
- footer.envLabel && footer.envLabel.trim().toLowerCase() !== "production" ? /* @__PURE__ */ jsxRuntime.jsxs(
2743
+ footer.links && footer.links.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap items-center justify-center gap-[6px] text-[11px] leading-[1.2] ${footer.user ? "mt-3" : ""} ${rc("max-md:hidden")}`, children: footer.links.map((l, i) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
2744
+ i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))]", children: "\xB7" }) : null,
2745
+ /* @__PURE__ */ jsxRuntime.jsx(
2746
+ "a",
2747
+ {
2748
+ href: safeHref(l.href),
2749
+ className: "text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:text-[color:var(--sidebar-text,var(--foreground))] hover:underline",
2750
+ children: l.label
2751
+ }
2752
+ )
2753
+ ] }, l.label)) }) : null,
2754
+ footer.envLabel || footer.commit || footer.version ? /* @__PURE__ */ jsxRuntime.jsxs(
2757
2755
  "div",
2758
2756
  {
2759
2757
  "data-shell-meta": true,
2760
- className: `mt-1.5 flex flex-col items-start gap-0.5 font-[family-name:var(--font-plex-mono)] text-[10px] text-[color:var(--sidebar-meta-text,var(--sidebar-text))] ${rc("max-md:hidden")}`,
2758
+ className: `mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-plex-mono)] text-[11px] text-[color:var(--sidebar-meta-text,rgba(255,255,255,0.4))] ${rc("max-md:hidden")}`,
2761
2759
  children: [
2762
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
2763
- /* @__PURE__ */ jsxRuntime.jsx(
2764
- "span",
2765
- {
2766
- className: [
2767
- "rounded-md px-1.5 py-0.5 text-[10px] font-semibold",
2768
- envChipClasses(footer.envLabel)
2769
- ].join(" "),
2770
- children: footer.envLabel
2771
- }
2772
- ),
2773
- footer.commit ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2774
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[color:var(--muted)]", children: "|" }),
2775
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: footer.commit.slice(-4) })
2776
- ] }) : null,
2777
- footer.version ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2778
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[color:var(--muted)]", children: "|" }),
2779
- /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
2780
- "v",
2781
- footer.version
2782
- ] })
2783
- ] }) : null
2784
- ] }),
2760
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: [
2761
+ footer.envLabel ? shortEnvLabel(footer.envLabel) : null,
2762
+ footer.commit ? footer.commit.slice(-4) : null,
2763
+ footer.version ? `v${footer.version.replace(/^v/, "")}` : null
2764
+ ].filter((v) => Boolean(v)).map((v, i) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
2765
+ i > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: "|" }) : null,
2766
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: v })
2767
+ ] }, i)) }),
2785
2768
  footer.commitDate || footer.commitAuthor ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
2786
2769
  footer.commitDate ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: new Date(footer.commitDate).toLocaleDateString(void 0, {
2787
2770
  month: "short",
2788
2771
  day: "numeric"
2789
2772
  }) }) : null,
2790
- footer.commitDate && footer.commitAuthor ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[color:var(--muted)]", children: "|" }) : null,
2773
+ footer.commitDate && footer.commitAuthor ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: "|" }) : null,
2791
2774
  footer.commitAuthor ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: footer.commitAuthor.split(/\s+/)[0] }) : null
2792
2775
  ] }) : null
2793
2776
  ]
@@ -5197,7 +5180,7 @@ function ChromeTopBarActions() {
5197
5180
  function ChromeDevNotesMenu() {
5198
5181
  const { ready, openTasks, activate } = react.useContext(DevNotesTasksContext);
5199
5182
  if (!ready) return null;
5200
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "contents" }, onPointerDownCapture: activate, onFocusCapture: activate, onKeyDownCapture: activate, children: /* @__PURE__ */ jsxRuntime.jsx(devnotes.DevNotesMenu, { position: "top-right", onViewTasks: openTasks }) });
5183
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "contents" }, onPointerDownCapture: activate, onFocusCapture: activate, onKeyDownCapture: activate, children: /* @__PURE__ */ jsxRuntime.jsx(devnotes.DevNotesMenu, { position: "top-right", icon: lu.LuNotebookPen, onViewTasks: openTasks }) });
5201
5184
  }
5202
5185
  function useIsSuperAdmin() {
5203
5186
  const state = useChromeState();