@the-portland-company/shell 0.9.0 → 0.10.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 CHANGED
@@ -1,3 +1,35 @@
1
+ ## 0.10.2 — 2026-07-13
2
+
3
+ ### Security (XSS) + UI
4
+
5
+ - **Sanitize host-supplied hrefs** in native NavLink / footer / action links
6
+ (`safeHref` blocks `javascript:`/`data:` URL schemes) — merged from the
7
+ skills-scan security review. `npm audit` added to prepublish.
8
+ - **Smaller OrgPill badge** (`28px` → `20px`) — carried forward from 0.10.1.
9
+
10
+ This is a single publish combining the XSS fix (was on `main` @ 0.10.0) and the
11
+ OrgPill change (was on `feat/orgpill-smaller-badge` @ 0.10.1).
12
+
13
+ ## 0.10.1 — 2026-07-13
14
+
15
+ ### Changed (OrgPill)
16
+
17
+ - **Sidebar org switcher badge is smaller** (`28px` → `20px`) so the initials/logo
18
+ circle no longer nearly fills the `sm` MenuButton — gives visible top/bottom
19
+ breathing room. Only the icon size changed; the pill's colors/background and the
20
+ dropdown are untouched (light/dark styling unchanged).
21
+
22
+ ## 0.10.0 — 2026-07-12
23
+
24
+ ### Fixed (Specs brand colors)
25
+
26
+ - **Brand ramp is Specs race-red (`#E63946`)**, not legacy burnt-orange (`#E86A3A`).
27
+ `gen:tokens` now emits `--app-color-brand-*` and Chakra `brand` from `colors.raceRed`.
28
+ - Mode defaults, focus ring, and field focus use relationship primary / race-red.
29
+ - Sidebar footer Privacy/Terms/Subscriptions links use race-red (not theme orange).
30
+ - OrgPill fallbacks, nav badges, support button: race-red / `red` scheme.
31
+
32
+
1
33
  # Changelog
2
34
 
3
35
  ## 0.9.0 — 2026-07-12
package/dist/chrome.css CHANGED
@@ -112,8 +112,8 @@
112
112
  --surface-2: #ECEEEF;
113
113
  --surface-3: #FFFFFF;
114
114
 
115
- /* Focus ring */
116
- --focus-ring-color: #E86A3A;
115
+ /* Focus ring — Specs race-red (ignore stale orange focus.ringColor) */
116
+ --focus-ring-color: #E63946;
117
117
  --focus-ring-width: 3px;
118
118
  --focus-ring-offset: 0px;
119
119
 
@@ -172,17 +172,17 @@
172
172
  --topbar-icon-button-size: 32px;
173
173
  --topbar-icon-size: 20px;
174
174
 
175
- /* Shell chrome: brand color ramps */
176
- --app-color-brand-50: #FFF5F0;
177
- --app-color-brand-100: #FFE8DC;
178
- --app-color-brand-200: #FFD0B8;
179
- --app-color-brand-300: #FFB088;
180
- --app-color-brand-400: #FF8C5A;
181
- --app-color-brand-500: #E86A3A;
182
- --app-color-brand-600: #CC5429;
183
- --app-color-brand-700: #A6421F;
184
- --app-color-brand-800: #803317;
185
- --app-color-brand-900: #5C2410;
175
+ /* Shell chrome: brand color ramps (= Specs race-red) */
176
+ --app-color-brand-50: #FDECEE;
177
+ --app-color-brand-100: #FCE0E3;
178
+ --app-color-brand-200: #F8B6BD;
179
+ --app-color-brand-300: #EF6671;
180
+ --app-color-brand-400: #EA4751;
181
+ --app-color-brand-500: #E63946;
182
+ --app-color-brand-600: #C42E3A;
183
+ --app-color-brand-700: #9F252E;
184
+ --app-color-brand-800: #660F17;
185
+ --app-color-brand-900: #39080D;
186
186
 
187
187
  /* Shell chrome: gray ramps */
188
188
  --app-color-gray-50: #F7FAFC;
@@ -200,7 +200,7 @@
200
200
  --app-field-bg: #FFFFFF;
201
201
  --app-field-border: #E2E8F0;
202
202
  --app-field-border-hover: #A0AEC0;
203
- --app-field-focus: #E86A3A;
203
+ --app-field-focus: #E63946;
204
204
  --app-field-radius: 10px;
205
205
  --form-placeholder-font-size: 14px;
206
206
  --form-select-icon: #64748B;
@@ -215,8 +215,8 @@
215
215
  --app-btn-size: 44px;
216
216
  --app-btn-radius: 10px;
217
217
  --app-btn-font-size: 14px;
218
- --app-btn-primary-bg: #E86A3A;
219
- --app-btn-primary-bg-hover: #D95F30;
218
+ --app-btn-primary-bg: #E63946;
219
+ --app-btn-primary-bg-hover: #C42E3A;
220
220
  --app-btn-primary-fg: #FFFFFF;
221
221
  --app-btn-secondary-bg: #FFFFFF;
222
222
  --app-btn-secondary-bg-hover: #F8FAFC;
@@ -236,10 +236,10 @@
236
236
  --app-tab-radius: 12px;
237
237
 
238
238
  /* Mode-active colors (overwritten by app at mode-switch time) */
239
- --mode-primary-color: #E86A3A;
240
- --mode-input-border-color: #E86A3A;
241
- --mode-input-hover-border-color: #CC5429;
242
- --mode-input-focus-shadow-color: #E86A3A;
239
+ --mode-primary-color: #E63946;
240
+ --mode-input-border-color: #E63946;
241
+ --mode-input-hover-border-color: #C42E3A;
242
+ --mode-input-focus-shadow-color: #E63946;
243
243
  }
244
244
  .dark {
245
245
  --background: 222.2 84% 4.9%;
package/dist/index.cjs CHANGED
@@ -15,11 +15,11 @@ var clsx2__default = /*#__PURE__*/_interopDefault(clsx2);
15
15
  // src/theme/index.ts
16
16
 
17
17
  // src/theme/tokens.generated.ts
18
- var brandRamp = { 50: "#FFF5F0", 100: "#FFE8DC", 200: "#FFD0B8", 300: "#FFB088", 400: "#FF8C5A", 500: "#E86A3A", 600: "#CC5429", 700: "#A6421F", 800: "#803317", 900: "#5C2410" };
18
+ var brandRamp = { 50: "#FDECEE", 100: "#FCE0E3", 200: "#F8B6BD", 300: "#EF6671", 400: "#EA4751", 500: "#E63946", 600: "#C42E3A", 700: "#9F252E", 800: "#660F17", 900: "#39080D" };
19
19
 
20
20
  // src/theme/colors.ts
21
21
  var colors = {
22
- // Primary brand color - Politogy burnt-orange (Energy & Action). From Specs.
22
+ // Primary brand = Specs race-red (#E63946 ramp). Generated via gen:tokens.
23
23
  brand: { ...brandRamp },
24
24
  // Politogy Brand Colors
25
25
  politogy: {
@@ -36,7 +36,7 @@ var colors = {
36
36
  800: "#2a4365",
37
37
  900: "#1a365d"
38
38
  },
39
- // Primary Red/Orange - Energy & Action (main brand color). From Specs.
39
+ // Race-red (Specs primary brand). Same ramp as `brand`.
40
40
  red: { ...brandRamp },
41
41
  // Navy - Professional & Authoritative
42
42
  navy: {
@@ -1872,7 +1872,7 @@ function NavItem({
1872
1872
  /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { flex: "1", children: [
1873
1873
  /* @__PURE__ */ jsxRuntime.jsx(react.Box, { children }),
1874
1874
  subLabel ? /* @__PURE__ */ jsxRuntime.jsx(react.Text, { mt: 0.5, fontSize: "10px", lineHeight: "1.3", color: "gray.400", children: subLabel }) : null,
1875
- badge && /* @__PURE__ */ jsxRuntime.jsx(react.Badge, { colorScheme: "orange", size: "xs", mt: 1, fontSize: "xs", display: "block", children: badge })
1875
+ badge && /* @__PURE__ */ jsxRuntime.jsx(react.Badge, { colorScheme: "red", size: "xs", mt: 1, fontSize: "xs", display: "block", children: badge })
1876
1876
  ] })
1877
1877
  ]
1878
1878
  }
@@ -2013,7 +2013,7 @@ function OrgPill() {
2013
2013
  () => currentOrg ? getOrganizationBrandColor(currentOrg) : null,
2014
2014
  [currentOrg]
2015
2015
  );
2016
- const selectedOrgColor = selectedOrgBrandColor || "var(--mode-primary-color, #ea6a3a)";
2016
+ const selectedOrgColor = selectedOrgBrandColor || "var(--mode-primary-color, var(--color-race-red-500, #E63946))";
2017
2017
  const selectedOrgMenuBg = selectedOrgBrandColor && lightenHexColor(selectedOrgBrandColor, 0.12) || "#4a4a4a";
2018
2018
  if (!org) return null;
2019
2019
  return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { mx: "4", mb: "3", children: [
@@ -2058,7 +2058,7 @@ function OrgPill() {
2058
2058
  name: currentOrg?.name,
2059
2059
  logoUrl: currentOrg?.logoUrl,
2060
2060
  brandColor: selectedOrgBrandColor,
2061
- size: "28px"
2061
+ size: "20px"
2062
2062
  }
2063
2063
  ),
2064
2064
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: currentOrg?.name || "No organizations" })
@@ -2087,15 +2087,15 @@ function OrgPill() {
2087
2087
  bg: "transparent",
2088
2088
  color: currentOrg?.id ? "white" : "inherit",
2089
2089
  _hover: {
2090
- bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2090
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#E63946", 0.2) || "#555555" : "gray.100",
2091
2091
  color: currentOrg?.id ? "white" : "gray.900"
2092
2092
  },
2093
2093
  _focus: {
2094
- bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2094
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#E63946", 0.2) || "#555555" : "gray.100",
2095
2095
  color: currentOrg?.id ? "white" : "gray.900"
2096
2096
  },
2097
2097
  _active: {
2098
- bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.24) || "#5d5d5d" : "gray.200",
2098
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#E63946", 0.24) || "#5d5d5d" : "gray.200",
2099
2099
  color: currentOrg?.id ? "white" : "gray.900"
2100
2100
  },
2101
2101
  children: /* @__PURE__ */ jsxRuntime.jsxs(react.Flex, { justify: "space-between", align: "center", width: "100%", overflow: "hidden", children: [
@@ -2145,15 +2145,15 @@ function OrgPill() {
2145
2145
  color: currentOrg?.id ? "white" : "inherit",
2146
2146
  my: 0,
2147
2147
  _hover: {
2148
- bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2148
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#E63946", 0.2) || "#555555" : "gray.100",
2149
2149
  color: currentOrg?.id ? "white" : "gray.900"
2150
2150
  },
2151
2151
  _focus: {
2152
- bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.2) || "#555555" : "gray.100",
2152
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#E63946", 0.2) || "#555555" : "gray.100",
2153
2153
  color: currentOrg?.id ? "white" : "gray.900"
2154
2154
  },
2155
2155
  _active: {
2156
- bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#ea6a3a", 0.24) || "#5d5d5d" : "gray.200",
2156
+ bg: currentOrg?.id ? lightenHexColor(selectedOrgBrandColor || "#E63946", 0.24) || "#5d5d5d" : "gray.200",
2157
2157
  color: currentOrg?.id ? "white" : "gray.900"
2158
2158
  },
2159
2159
  fontSize: "sm",
@@ -2571,7 +2571,11 @@ function Sidebar({ onClose, id }) {
2571
2571
  {
2572
2572
  href: l.href,
2573
2573
  isExternal: true,
2574
- _hover: { textDecoration: "underline", opacity: 1 },
2574
+ color: "var(--color-race-red-500, #E63946)",
2575
+ _hover: {
2576
+ color: "var(--color-race-red-600, #C42E3A)",
2577
+ textDecoration: "underline"
2578
+ },
2575
2579
  children: l.label
2576
2580
  }
2577
2581
  ) : /* @__PURE__ */ jsxRuntime.jsx(
@@ -2579,7 +2583,11 @@ function Sidebar({ onClose, id }) {
2579
2583
  {
2580
2584
  as: reactRouterDom.NavLink,
2581
2585
  to: l.href,
2582
- _hover: { textDecoration: "underline", opacity: 1 },
2586
+ color: "var(--color-race-red-500, #E63946)",
2587
+ _hover: {
2588
+ color: "var(--color-race-red-600, #C42E3A)",
2589
+ textDecoration: "underline"
2590
+ },
2583
2591
  children: l.label
2584
2592
  }
2585
2593
  )
@@ -2894,7 +2902,7 @@ ${formatted}` : formatted,
2894
2902
  /* @__PURE__ */ jsxRuntime.jsx(
2895
2903
  react.Button,
2896
2904
  {
2897
- colorScheme: "orange",
2905
+ colorScheme: "red",
2898
2906
  onClick: () => void handleSubmit(),
2899
2907
  isLoading: isSubmitting,
2900
2908
  loadingText: "Sending",