@the-portland-company/shell 0.75.0 → 0.75.2
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 +17 -0
- package/dist/app-chrome.cjs +30 -19
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.js +28 -17
- package/dist/app-chrome.js.map +1 -1
- package/dist/chrome.css +39 -7
- package/dist/{chunk-QUXD4PZ7.js → chunk-2DXTSTII.js} +10 -8
- package/dist/chunk-2DXTSTII.js.map +1 -0
- package/dist/index.cjs +33 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +33 -3
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +8 -6
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +6 -3
- package/dist/native.d.ts +6 -3
- package/dist/native.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-QUXD4PZ7.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## 0.75.2
|
|
2
|
+
|
|
3
|
+
Two fixes found on top of 0.75.1:
|
|
4
|
+
|
|
5
|
+
- **Contrast (item 4).** Several rail/mono text colors were tuned only against the ink rail (`#1B1C20`) and dropped below WCAG 2.2 AA's 4.5:1 minimum for normal-size text on the Campaign-mode red rail (`#8F1F2A`, raised card `#A12430`) and the loading screen (`#0a0a0c`): the account-menu "Roles & Organizations" caption (`--muted` / `--topbar-breadcrumb-color`, 3.63:1 on `--panel-elevated`), the sidebar user-email/mode caption (`--sidebar-caption`, 3.25:1 on the Campaign rail), the org-id hash (2.93:1 on the Campaign card), the nav section eyebrow (`--sidebar-eyebrow`, 3.55:1 even on the ink rail), and the loading-screen footer tagline (inline literal, 3.50:1). Fixed entirely through tokens: `--topbar-breadcrumb-color` darkened to `#5C6B80`; `--sidebar-text-muted`/`--sidebar-meta-text` lightened to `#CDCFD2`; `--sidebar-eyebrow`/`--sidebar-caption`/`--sidebar-row-text` raised to `rgba(255,255,255,.72)`/`.66`; the loading-screen's two `rgba(255,255,255,0.38)` literals (footer tagline and the error-state "Sign out" button) raised to `0.72`; and `native/index.tsx`'s hardcoded `--sidebar-meta-text` fallback updated to match. Each value clears 4.5:1 against every background it can actually render on (ink rail, Campaign rail, Campaign card, loading-screen ink, white/`--panel-elevated`), not just the one it was first tuned against. New test: `__tests__/sidebarContrast.test.ts` computes WCAG relative-luminance contrast for each token/background pair and fails the build if any drops below 4.5:1.
|
|
6
|
+
- **Missing `title` grant (item 5).** `POLITOGY_APPS.forms` had no `title` grant, so Forms could never publish a real per-page title — the page header fell back to the static registry title "Forms" forever and the designed "mode" eyebrow + H2 + subtitle block never rendered with real page data. Same gap existed on every other feature app with real per-page names: `surveys`, `polls`, `ctas`, `email`, `a2p`, `phonebank`, `canvass`, `signs` all got `grants: ['title']` added, by the same reasoning already applied to `petitions`. Left `dashboard` and `settings` (no per-record pages), `contacts` (already `pageTitle: false`), and `vrm` (core, gated by `app === CORE_APP` instead) ungranted. `__tests__/frame-grants.test.tsx` rewritten to assert the full grant set explicitly.
|
|
7
|
+
|
|
8
|
+
**Noted, not fixed:** UI-Platform (v44) says the `breadcrumbs` grant was retired 2026-09-30, but `petitions` still carries `grants: ['breadcrumbs', 'title']` and the `PolitogyFrameGrant` type still includes `'breadcrumbs'`. Removing it touches `deriveBreadcrumbs`, the `NavBreadcrumb` type, `PolitogyGrantedFrame.breadcrumbs`/`PolitogyCoreFrame.page.breadcrumbs`, and the `breadcrumbs` prop threaded into `NavTopBar` — out of scope for this release. Flagging per spec-is-source-of-truth rather than doing an unscoped removal.
|
|
9
|
+
|
|
10
|
+
## 0.75.1
|
|
11
|
+
|
|
12
|
+
Three visual-regression fixes found by cross-app comparison (every app diverged from the design the same three ways):
|
|
13
|
+
|
|
14
|
+
- **Font tokens.** `--font-sans`, `--font-mono` and `--font-plex-mono` were referenced across `loading-screen.tsx` and `native/index.tsx` (and `theme/index.ts` read `--type-mono-family`) but `chrome.css` never emitted any of them, so those surfaces silently fell back to a hardcoded system stack instead of the Brand `--font-family` token — the actual source of the Inter/Acumin mismatch. Every sans surface now consumes `--font-family` (the one token the Brand API emits); every mono surface now consumes one shared, shell-emitted `--font-mono` (also added to `scripts/gen-tokens.mjs`).
|
|
15
|
+
- **Card tokens.** `--color-panel` aliased `--color-surface` (`--surface-1`, #F0F4F7 — the PAGE background), so every card rendered page-tinted instead of the Brand Card white. `--color-border` aliased `--line` / `--sidebar-border`, a token scoped to the always-dark left rail, leaking a dark-rail-intended border onto light content. Fixed in `chrome.css` (and `gen-tokens.mjs`): `--color-panel` is now `--color-layer-3` (white); `--color-border` is now `--color-g3` (#D7DADF, the neutral Brand border step).
|
|
16
|
+
- **Mode eyebrow + tab icons.** `PageHeader` had no `mode`/`eyebrow` prop at all, so the 11px uppercase mode eyebrow (Reference/UI-Platform → "Page header") never had anywhere to render; it now renders by default whenever `mode` is passed (`showEyebrow`/`eyebrow` to override). `NavTab.icon` was marked `@deprecated` and explicitly not rendered as of 0.69.0 — reversed by the 2026-10-06 Tabs decision ("Icon + label. Each tab is a Lucide icon") — `NavTabStrip` now renders the icon again, 15px (13px on `size="sm"`), 1.75 stroke, 6px left of the label, following the label's color via `currentColor`.
|
|
17
|
+
|
|
1
18
|
## 0.75.0
|
|
2
19
|
|
|
3
20
|
Built on top of 0.74.0 (`claude/retire-nav`). Two fixes:
|
package/dist/app-chrome.cjs
CHANGED
|
@@ -2896,7 +2896,7 @@ function NavSidebar({
|
|
|
2896
2896
|
"div",
|
|
2897
2897
|
{
|
|
2898
2898
|
"data-shell-meta": true,
|
|
2899
|
-
className: `mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-
|
|
2899
|
+
className: `mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] text-[color:var(--sidebar-meta-text,rgba(255,255,255,0.72))] ${rc("max-md:hidden")}`,
|
|
2900
2900
|
children: [
|
|
2901
2901
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: [
|
|
2902
2902
|
footer.envLabel ? shortEnvLabel(footer.envLabel) : null,
|
|
@@ -3046,7 +3046,7 @@ function NavActiveRail() {
|
|
|
3046
3046
|
function NavRowBadge({ value }) {
|
|
3047
3047
|
const rc = useRailCollapse();
|
|
3048
3048
|
if (value === void 0 || value === null || value === "") return null;
|
|
3049
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `ml-auto shrink-0 font-[family-name:var(--font-
|
|
3049
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `ml-auto shrink-0 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] font-semibold leading-none text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] ${rc("max-md:hidden")}`, children: value });
|
|
3050
3050
|
}
|
|
3051
3051
|
function NavSectionRow({
|
|
3052
3052
|
label,
|
|
@@ -3160,7 +3160,7 @@ function OrgIdCopyButton({ id }) {
|
|
|
3160
3160
|
setTimeout(() => setCopied(false), 1500);
|
|
3161
3161
|
},
|
|
3162
3162
|
title: "Copy organization id",
|
|
3163
|
-
className: "-ml-1 rounded px-1 text-left font-[family-name:var(--font-
|
|
3163
|
+
className: "-ml-1 rounded px-1 text-left font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))]",
|
|
3164
3164
|
children: copied ? "Copied" : `\u2026${id.slice(-8)}`
|
|
3165
3165
|
}
|
|
3166
3166
|
);
|
|
@@ -3220,7 +3220,7 @@ function NavTopBar({
|
|
|
3220
3220
|
"kbd",
|
|
3221
3221
|
{
|
|
3222
3222
|
"aria-hidden": true,
|
|
3223
|
-
className: "pointer-events-none absolute right-[10px] hidden md:block rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-
|
|
3223
|
+
className: "pointer-events-none absolute right-[10px] hidden md:block rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--muted)]",
|
|
3224
3224
|
children: "/"
|
|
3225
3225
|
}
|
|
3226
3226
|
)
|
|
@@ -4243,7 +4243,7 @@ function LoadingScreen({
|
|
|
4243
4243
|
display: "flex",
|
|
4244
4244
|
alignItems: "center",
|
|
4245
4245
|
gap: "0.6rem",
|
|
4246
|
-
fontFamily: "var(--font-
|
|
4246
|
+
fontFamily: "var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)"
|
|
4247
4247
|
},
|
|
4248
4248
|
children: [
|
|
4249
4249
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4337,7 +4337,7 @@ function LoadingScreen({
|
|
|
4337
4337
|
border: "none",
|
|
4338
4338
|
background: "var(--color-race-red, #dc2626)",
|
|
4339
4339
|
color: "#fff",
|
|
4340
|
-
fontFamily: "var(--font-
|
|
4340
|
+
fontFamily: "var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)",
|
|
4341
4341
|
fontSize: "0.875rem",
|
|
4342
4342
|
fontWeight: 600,
|
|
4343
4343
|
cursor: "pointer"
|
|
@@ -4355,8 +4355,10 @@ function LoadingScreen({
|
|
|
4355
4355
|
padding: 0,
|
|
4356
4356
|
border: "none",
|
|
4357
4357
|
background: "transparent",
|
|
4358
|
-
|
|
4359
|
-
|
|
4358
|
+
// 0.38 alpha was 3.51:1 on the ink-900 loading background —
|
|
4359
|
+
// below WCAG 2.2 AA 4.5:1. 0.72 clears it.
|
|
4360
|
+
color: "rgba(255,255,255,0.72)",
|
|
4361
|
+
fontFamily: "var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)",
|
|
4360
4362
|
fontSize: "12.5px",
|
|
4361
4363
|
textDecoration: "underline",
|
|
4362
4364
|
cursor: "pointer"
|
|
@@ -4380,9 +4382,11 @@ function LoadingScreen({
|
|
|
4380
4382
|
alignItems: "center",
|
|
4381
4383
|
justifyContent: "space-between",
|
|
4382
4384
|
padding: "0 32px 30px",
|
|
4383
|
-
fontFamily: "var(--font-
|
|
4385
|
+
fontFamily: "var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)",
|
|
4384
4386
|
fontSize: "12.5px",
|
|
4385
|
-
|
|
4387
|
+
// 0.38 alpha was 3.51:1 on the ink-900 loading background — below
|
|
4388
|
+
// WCAG 2.2 AA 4.5:1. 0.72 clears it.
|
|
4389
|
+
color: "rgba(255,255,255,0.72)"
|
|
4386
4390
|
},
|
|
4387
4391
|
children: [
|
|
4388
4392
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Politogy VRM. Built for the long game." }),
|
|
@@ -4450,11 +4454,17 @@ var POLITOGY_APPS = {
|
|
|
4450
4454
|
storagePrefix: "contacts",
|
|
4451
4455
|
pageTitle: false
|
|
4452
4456
|
},
|
|
4453
|
-
|
|
4454
|
-
|
|
4457
|
+
// 'title' for forms/surveys/polls/ctas for the same reason as petitions
|
|
4458
|
+
// below: their pages have real names ("Volunteer Signup", "Q3 Satisfaction"),
|
|
4459
|
+
// where the registry can only say the app's own name. Without the grant the
|
|
4460
|
+
// page header falls back to the static registry title forever, so the
|
|
4461
|
+
// designed "<mode> mode" eyebrow + H2 + subtitle block never gets the real
|
|
4462
|
+
// per-page title an app passes it (UI-Platform → Page header).
|
|
4463
|
+
forms: { title: "Forms", origin: "https://forms.politogyvrm.com", storagePrefix: "forms", grants: ["title"] },
|
|
4464
|
+
surveys: { title: "Surveys", origin: "https://surveys.politogyvrm.com", storagePrefix: "surveys", grants: ["title"] },
|
|
4455
4465
|
// Specs/Left-Navigation §9.2: Polling is a Campaign row (Research).
|
|
4456
|
-
polls: { title: "Polls", origin: "https://polls.politogyvrm.com", storagePrefix: "polls", mode: "campaign" },
|
|
4457
|
-
ctas: { title: "CTAs", origin: "https://ctas.politogyvrm.com", storagePrefix: "ctas" },
|
|
4466
|
+
polls: { title: "Polls", origin: "https://polls.politogyvrm.com", storagePrefix: "polls", mode: "campaign", grants: ["title"] },
|
|
4467
|
+
ctas: { title: "CTAs", origin: "https://ctas.politogyvrm.com", storagePrefix: "ctas", grants: ["title"] },
|
|
4458
4468
|
// V2 apps that replace retired app.politogyvrm.com pages (Reference/
|
|
4459
4469
|
// UI-Platform v42 "Retirement of app.politogyvrm.com"). Dashboard hosts the
|
|
4460
4470
|
// Relationship Dashboard + Campaign Battleground/District data/Campaigns
|
|
@@ -4478,7 +4488,7 @@ var POLITOGY_APPS = {
|
|
|
4478
4488
|
},
|
|
4479
4489
|
// Relationship Mode Email Engine (Specs/Email-Engine) — the V2 standalone
|
|
4480
4490
|
// app, running in parallel to VRM core's V1 Email Broadcast.
|
|
4481
|
-
email: { title: "Email", origin: "https://email.politogyvrm.com", storagePrefix: "email", mode: "relationship" },
|
|
4491
|
+
email: { title: "Email", origin: "https://email.politogyvrm.com", storagePrefix: "email", mode: "relationship", grants: ["title"] },
|
|
4482
4492
|
// Campaign Mode apps — each scoped to Campaign, so they render the Campaign
|
|
4483
4493
|
// tree and a static Campaign pill. Not yet deployed; hidden from the Campaign
|
|
4484
4494
|
// nav by CAMPAIGN_FEATURE_AVAILABILITY until their launch flips the flag.
|
|
@@ -4491,11 +4501,12 @@ var POLITOGY_APPS = {
|
|
|
4491
4501
|
origin: "https://a2p.politogyvrm.com",
|
|
4492
4502
|
storagePrefix: "a2p",
|
|
4493
4503
|
mode: "campaign",
|
|
4494
|
-
dual: { modes: ["relationship", "campaign"], defaultMode: "campaign" }
|
|
4504
|
+
dual: { modes: ["relationship", "campaign"], defaultMode: "campaign" },
|
|
4505
|
+
grants: ["title"]
|
|
4495
4506
|
},
|
|
4496
|
-
phonebank: { title: "Phone Banking", origin: "https://phonebank.politogyvrm.com", storagePrefix: "phonebank", mode: "campaign" },
|
|
4497
|
-
canvass: { title: "Field Canvassing", origin: "https://canvass.politogyvrm.com", storagePrefix: "canvass", mode: "campaign" },
|
|
4498
|
-
signs: { title: "Sign Mapping", origin: "https://signs.politogyvrm.com", storagePrefix: "signs", mode: "campaign" }
|
|
4507
|
+
phonebank: { title: "Phone Banking", origin: "https://phonebank.politogyvrm.com", storagePrefix: "phonebank", mode: "campaign", grants: ["title"] },
|
|
4508
|
+
canvass: { title: "Field Canvassing", origin: "https://canvass.politogyvrm.com", storagePrefix: "canvass", mode: "campaign", grants: ["title"] },
|
|
4509
|
+
signs: { title: "Sign Mapping", origin: "https://signs.politogyvrm.com", storagePrefix: "signs", mode: "campaign", grants: ["title"] }
|
|
4499
4510
|
};
|
|
4500
4511
|
var DEFAULT_SEARCH_PLACEHOLDER = {
|
|
4501
4512
|
contacts: "Search contacts, segments, forms"
|