@the-portland-company/shell 0.68.0 → 0.68.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,9 @@
1
+ ## 0.68.1 — 2026-10-03
2
+
3
+ ### Fixed
4
+
5
+ - **Dark theme: chrome whites stay white.** The Brand token sheet remaps `--color-white` to `#0A0A0A` under `.dark`, and Tailwind's `bg-white` / `text-white` read it, so the org logo band went near-black behind its dark wordmark and white labels on accent fills (avatars, badges, active group headers) went near-black. Chrome now uses the literal `[#FFFFFF]`. Regression test: `__tests__/chrome-fixed-white.test.ts`.
6
+
1
7
  ## 0.68.0 — 2026-10-03
2
8
 
3
9
  Contacts design parity for the `chrome` Design Compare kind (Specs/Contacts v25 design frames `00-welcome-ben` 1440×900 / 390×844). Additive props only; every existing consumer prop keeps working.
@@ -215,7 +215,7 @@ function useAnyTopBarPanelOpen() {
215
215
  }
216
216
  function TopBarCountBadge({ count }) {
217
217
  if (!(count > 0)) return null;
218
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger)] px-1 text-[10px] font-bold leading-4 text-white", children: count > 99 ? "99+" : count });
218
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger)] px-1 text-[10px] font-bold leading-4 text-[#FFFFFF]", children: count > 99 ? "99+" : count });
219
219
  }
220
220
  function TopBarTooltip({
221
221
  title,
@@ -285,7 +285,7 @@ function NavThemeControl({
285
285
  onClick: () => onChange(opt.value),
286
286
  className: [
287
287
  "flex-1 px-3 py-1.5 text-xs font-semibold transition",
288
- value === opt.value ? "bg-[color:var(--color-accent)] text-white" : "text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]"
288
+ value === opt.value ? "bg-[color:var(--color-accent)] text-[#FFFFFF]" : "text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]"
289
289
  ].join(" "),
290
290
  children: opt.label
291
291
  },
@@ -629,7 +629,7 @@ function LowFuelHint({ lowFuel, orgId }) {
629
629
  "div",
630
630
  {
631
631
  role: "status",
632
- className: "absolute right-0 top-[calc(100%+10px)] z-50 w-60 rounded-lg border border-[color:var(--chrome-danger)] bg-[color:var(--chrome-danger)] px-3 py-2 text-white shadow-[var(--shadow-soft)]",
632
+ className: "absolute right-0 top-[calc(100%+10px)] z-50 w-60 rounded-lg border border-[color:var(--chrome-danger)] bg-[color:var(--chrome-danger)] px-3 py-2 text-[#FFFFFF] shadow-[var(--shadow-soft)]",
633
633
  onClick: (e) => e.stopPropagation(),
634
634
  children: [
635
635
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -657,7 +657,7 @@ function LowFuelHint({ lowFuel, orgId }) {
657
657
  type: "button",
658
658
  "aria-label": "Dismiss low fuel notice",
659
659
  onClick: dismiss,
660
- className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-white/90 transition hover:bg-white/20",
660
+ className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[#FFFFFF]/90 transition hover:bg-[#FFFFFF]/20",
661
661
  children: /* @__PURE__ */ jsxRuntime.jsx(XGlyph, {})
662
662
  }
663
663
  )
@@ -841,7 +841,7 @@ function NewReplyToast({
841
841
  activate();
842
842
  }
843
843
  },
844
- className: "absolute right-[-6px] top-[calc(100%+12px)] z-50 min-w-[240px] max-w-[320px] cursor-pointer rounded-xl bg-[#161616] px-4 py-3 text-white shadow-[var(--shadow-soft)]",
844
+ className: "absolute right-[-6px] top-[calc(100%+12px)] z-50 min-w-[240px] max-w-[320px] cursor-pointer rounded-xl bg-[#161616] px-4 py-3 text-[#FFFFFF] shadow-[var(--shadow-soft)]",
845
845
  style: {
846
846
  opacity: visible ? 1 : 0,
847
847
  transform: visible ? "translateY(0px)" : "translateY(-4px)",
@@ -865,7 +865,7 @@ function NewReplyToast({
865
865
  setVisible(false);
866
866
  onClose();
867
867
  },
868
- className: "absolute right-2 top-2 flex h-5 w-5 items-center justify-center rounded-full text-white opacity-60 transition hover:bg-white/10 hover:opacity-100",
868
+ className: "absolute right-2 top-2 flex h-5 w-5 items-center justify-center rounded-full text-[#FFFFFF] opacity-60 transition hover:bg-[#FFFFFF]/10 hover:opacity-100",
869
869
  children: /* @__PURE__ */ jsxRuntime.jsx(XGlyph, { size: 12 })
870
870
  }
871
871
  ),
@@ -880,7 +880,7 @@ function NewReplyToast({
880
880
  setVisible(false);
881
881
  onSilence();
882
882
  },
883
- className: "mt-2 inline-flex items-center gap-1 text-[11px] font-semibold text-white opacity-60 transition hover:opacity-100",
883
+ className: "mt-2 inline-flex items-center gap-1 text-[11px] font-semibold text-[#FFFFFF] opacity-60 transition hover:opacity-100",
884
884
  children: [
885
885
  /* @__PURE__ */ jsxRuntime.jsx(BellOffGlyph, { size: 12 }),
886
886
  "Silence notifications"
@@ -1253,7 +1253,7 @@ function SupportAction({ orgId } = {}) {
1253
1253
  {
1254
1254
  type: "button",
1255
1255
  onClick: close,
1256
- className: "rounded-full bg-[color:var(--color-accent)] px-4 py-2 text-sm font-semibold text-white hover:opacity-90",
1256
+ className: "rounded-full bg-[color:var(--color-accent)] px-4 py-2 text-sm font-semibold text-[#FFFFFF] hover:opacity-90",
1257
1257
  children: "Done"
1258
1258
  }
1259
1259
  ) })
@@ -1313,7 +1313,7 @@ function SupportAction({ orgId } = {}) {
1313
1313
  type: "button",
1314
1314
  onClick: submit,
1315
1315
  disabled: !message.trim() || state === "sending",
1316
- className: "rounded-full bg-[color:var(--color-accent)] px-4 py-2 text-sm font-semibold text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",
1316
+ className: "rounded-full bg-[color:var(--color-accent)] px-4 py-2 text-sm font-semibold text-[#FFFFFF] transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",
1317
1317
  children: state === "sending" ? "Sending\u2026" : "Send request"
1318
1318
  }
1319
1319
  )
@@ -1549,7 +1549,7 @@ function SpecOverlayAction({ orgId, orgName } = {}) {
1549
1549
  "span",
1550
1550
  {
1551
1551
  className: [
1552
- "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-normal leading-none text-white",
1552
+ "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-normal leading-none text-[#FFFFFF]",
1553
1553
  status && status.matched ? status.passed ? "bg-[color:var(--chrome-success,#2f855a)]" : "bg-[color:var(--chrome-danger)]" : "bg-[color:var(--muted)]"
1554
1554
  ].join(" "),
1555
1555
  children: badgeLabel
@@ -2281,7 +2281,7 @@ function NavSidebar({
2281
2281
  className: "h-[var(--sidebar-brand-logo-height,24px)] w-auto object-contain"
2282
2282
  }
2283
2283
  ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2284
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-9 w-9 items-center justify-center rounded-xl bg-[color:var(--color-accent)] text-base font-black text-white shadow-sm", children: brand.badgeLabel }),
2284
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-9 w-9 items-center justify-center rounded-xl bg-[color:var(--color-accent)] text-base font-black text-[#FFFFFF] shadow-sm", children: brand.badgeLabel }),
2285
2285
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col leading-tight", children: [
2286
2286
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-extrabold tracking-[-0.01em] text-[color:var(--color-accent)]", children: brand.title }),
2287
2287
  brand.subtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-[color:var(--muted)]", children: brand.subtitle }) : null
@@ -2314,7 +2314,7 @@ function NavSidebar({
2314
2314
  style: orgCardStyle,
2315
2315
  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",
2316
2316
  children: [
2317
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative flex h-[var(--sidebar-org-band-height,48px)] w-full items-center justify-center bg-white px-3 py-[7px]", children: [
2317
+ /* @__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]", children: [
2318
2318
  orgLogoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: orgLogoSrc, alt: "", className: "max-h-full max-w-[132px] object-contain" }) : org.canUploadLogo ? /* @__PURE__ */ jsxRuntime.jsx(
2319
2319
  "a",
2320
2320
  {
@@ -2388,7 +2388,7 @@ function NavSidebar({
2388
2388
  "span",
2389
2389
  {
2390
2390
  style: { backgroundColor: o.brandColor || ORG_PILL_DEFAULT },
2391
- className: "flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-white",
2391
+ className: "flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-[#FFFFFF]",
2392
2392
  children: resolveOrgLogoUrl(o.logoUrl) ? /* @__PURE__ */ jsxRuntime.jsx(
2393
2393
  "img",
2394
2394
  {
@@ -2414,7 +2414,7 @@ function NavSidebar({
2414
2414
  style: orgCardStyle,
2415
2415
  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))]",
2416
2416
  children: [
2417
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative flex h-[var(--sidebar-org-band-height,48px)] w-full items-center justify-center bg-white px-3 py-[7px]", children: [
2417
+ /* @__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]", children: [
2418
2418
  orgLogoSrc ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: orgLogoSrc, alt: "", className: "max-h-full max-w-[132px] object-contain" }) : org.canUploadLogo ? /* @__PURE__ */ jsxRuntime.jsx(
2419
2419
  "a",
2420
2420
  {
@@ -2472,7 +2472,7 @@ function NavSidebar({
2472
2472
  disabled: !available,
2473
2473
  className: [
2474
2474
  "flex flex-1 items-center justify-center rounded-[5px] px-[9px] py-[6px] transition",
2475
- !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-white/5 hover:text-[color:var(--sidebar-text,var(--foreground))]"
2475
+ !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))]"
2476
2476
  ].join(" "),
2477
2477
  children: OptIcon ? /* @__PURE__ */ jsxRuntime.jsx(OptIcon, { size: 15, className: "shrink-0" }) : null
2478
2478
  },
@@ -2770,7 +2770,7 @@ function NavRow({
2770
2770
  const wrapperClasses = [
2771
2771
  "group relative block overflow-hidden transition",
2772
2772
  isSub ? "rounded-md" : "rounded-[5px]",
2773
- active ? activeClasses : isSub ? "text-[color:var(--sidebar-text,var(--muted))] hover:text-white" : NAV_TOP_INACTIVE_CLASS
2773
+ active ? activeClasses : isSub ? "text-[color:var(--sidebar-text,var(--muted))] hover:text-[#FFFFFF]" : NAV_TOP_INACTIVE_CLASS
2774
2774
  ].join(" ");
2775
2775
  const rowPadding = isSub ? "gap-3 px-3 py-1.5 text-[13px] font-semibold" : NAV_TOP_ROW_CLASS(active);
2776
2776
  const iconSize = isSub ? 16 : NAV_TOP_ICON_SIZE;
@@ -3049,7 +3049,7 @@ function NavTopBar({
3049
3049
  themeToggle,
3050
3050
  accountMenu === "topbar" ? /* @__PURE__ */ jsxRuntime.jsxs("details", { "data-nav-details": true, className: "group/acct relative", children: [
3051
3051
  /* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "group/tbtip relative flex cursor-pointer list-none items-center gap-2.5 rounded-full py-1 pl-1 pr-2 transition hover:bg-[color:var(--panel-elevated)] [&::-webkit-details-marker]:hidden", children: [
3052
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)] items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent)] text-xs font-bold text-white", children: user?.avatarUrl || user?.memojiUrl ? /* @__PURE__ */ jsxRuntime.jsx(
3052
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)] items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent)] text-xs font-bold text-[#FFFFFF]", children: user?.avatarUrl || user?.memojiUrl ? /* @__PURE__ */ jsxRuntime.jsx(
3053
3053
  "img",
3054
3054
  {
3055
3055
  src: user.avatarUrl || user.memojiUrl,
@@ -3148,7 +3148,7 @@ function NavAccountMenuPanel({
3148
3148
  },
3149
3149
  className: "flex min-w-0 flex-1 items-center gap-2.5 rounded-lg px-1 py-1 text-left hover:bg-[color:var(--panel)]",
3150
3150
  children: [
3151
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent)] text-[11px] font-bold text-white", children: a.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: a.avatarUrl, alt: "", className: "h-full w-full object-cover" }) : (a.name ?? a.email ?? "?").slice(0, 2).toUpperCase() }),
3151
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent)] text-[11px] font-bold text-[#FFFFFF]", children: a.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: a.avatarUrl, alt: "", className: "h-full w-full object-cover" }) : (a.name ?? a.email ?? "?").slice(0, 2).toUpperCase() }),
3152
3152
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col leading-tight", children: [
3153
3153
  /* @__PURE__ */ jsxRuntime.jsx(
3154
3154
  "span",
@@ -3259,7 +3259,7 @@ function NavSidebarUserCard({
3259
3259
  "aria-label": "My Account",
3260
3260
  className: "flex w-full cursor-pointer list-none items-center gap-[9px] rounded-[5px] px-1 py-1 text-left transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel-elevated))] [&::-webkit-details-marker]:hidden",
3261
3261
  children: [
3262
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--sidebar-avatar-bg,var(--color-accent))] text-[11px] font-bold text-white", children: user.avatarUrl || user.memojiUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: user.avatarUrl || user.memojiUrl, alt: "", className: "h-full w-full object-cover" }) : initials }),
3262
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--sidebar-avatar-bg,var(--color-accent))] text-[11px] font-bold text-[#FFFFFF]", children: user.avatarUrl || user.memojiUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: user.avatarUrl || user.memojiUrl, alt: "", className: "h-full w-full object-cover" }) : initials }),
3263
3263
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [
3264
3264
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[12px] font-semibold leading-[1.2] text-[color:var(--sidebar-text,var(--foreground))]", children: displayName }),
3265
3265
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[11px] leading-[1.3] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))]", children: secondary })
@@ -3309,7 +3309,7 @@ function NamePromptBubble({ profileHref, placement = "below" }) {
3309
3309
  "a",
3310
3310
  {
3311
3311
  href: safeHref(profileHref),
3312
- className: "rounded-full bg-[color:var(--color-accent)] px-3 py-1 text-xs font-semibold text-white hover:opacity-90",
3312
+ className: "rounded-full bg-[color:var(--color-accent)] px-3 py-1 text-xs font-semibold text-[#FFFFFF] hover:opacity-90",
3313
3313
  children: "Set name"
3314
3314
  }
3315
3315
  ) : null,
@@ -3393,7 +3393,7 @@ function NavTopBarActionButton({ action }) {
3393
3393
  const Glyph = BrandGlyph ?? Icon;
3394
3394
  const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3395
3395
  /* @__PURE__ */ jsxRuntime.jsx(Glyph, { size: TOPBAR_GLYPH_SIZE, className: "text-current" }),
3396
- typeof action.badge === "number" && action.badge > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger,var(--color-accent))] px-1 text-[10px] font-bold leading-4 text-white", children: action.badge }) : null,
3396
+ typeof action.badge === "number" && action.badge > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger,var(--color-accent))] px-1 text-[10px] font-bold leading-4 text-[#FFFFFF]", children: action.badge }) : null,
3397
3397
  /* @__PURE__ */ jsxRuntime.jsx(TopBarTooltip, { title: action.label, description: action.description })
3398
3398
  ] });
3399
3399
  const isExternal = action.href ? /^https?:\/\//.test(action.href) : false;