-
{initials}
+
{initials}
{name}
diff --git a/packages/web/src/features/staff/MileageReviewPage.tsx b/packages/web/src/features/staff/MileageReviewPage.tsx
index 6240d8d3..319e8fa5 100644
--- a/packages/web/src/features/staff/MileageReviewPage.tsx
+++ b/packages/web/src/features/staff/MileageReviewPage.tsx
@@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { getJson, patchJson } from '../../lib/api-client.js';
import { EmptyState, LoadingSkeleton, ErrorRetry } from '../../components/state/index.js';
+import { tint } from '../../lib/color.js';
/**
* Mileage review.
@@ -151,7 +152,7 @@ export function MileageReviewPage() {
{STATUS_TABS.find((t) => t.key === entry.status)?.label ?? entry.status}
diff --git a/packages/web/src/features/staff/StaffPage.tsx b/packages/web/src/features/staff/StaffPage.tsx
index 6d552d07..536b9d9b 100644
--- a/packages/web/src/features/staff/StaffPage.tsx
+++ b/packages/web/src/features/staff/StaffPage.tsx
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { getJson, postJson, patchJson, deleteJson } from '../../lib/api-client.js';
import { EmptyState, LoadingSkeleton, ErrorRetry } from '../../components/state/index.js';
+import { tint } from '../../lib/color.js';
interface StaffMember {
id: string;
@@ -104,7 +105,7 @@ function RoleBadge({ role }: { role: string }) {
{role}
);
}
diff --git a/packages/web/src/features/staff/TimeOffReviewPage.tsx b/packages/web/src/features/staff/TimeOffReviewPage.tsx
index 0187774b..229802a5 100644
--- a/packages/web/src/features/staff/TimeOffReviewPage.tsx
+++ b/packages/web/src/features/staff/TimeOffReviewPage.tsx
@@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useState } from 'react';
import { getJson, patchJson } from '../../lib/api-client.js';
import { EmptyState, LoadingSkeleton, ErrorRetry } from '../../components/state/index.js';
+import { tint } from '../../lib/color.js';
/**
* Time off review.
@@ -147,7 +148,7 @@ export function TimeOffReviewPage() {
{TABS.find((t) => t.key === req.status)?.label ?? req.status}
diff --git a/packages/web/src/features/superadmin/SuperAdminPage.tsx b/packages/web/src/features/superadmin/SuperAdminPage.tsx
index 04384276..25c12576 100644
--- a/packages/web/src/features/superadmin/SuperAdminPage.tsx
+++ b/packages/web/src/features/superadmin/SuperAdminPage.tsx
@@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useState } from 'react';
import { startRegistration, startAuthentication, browserSupportsWebAuthn } from '@simplewebauthn/browser';
import { BrandLogo } from '../../components/brand/BrandLogo.js';
+import { tint } from '../../lib/color.js';
/**
* Hidden platform super-admin command center for Durga Ghimeray (Founder & CEO).
@@ -441,14 +442,14 @@ export function SuperAdminPage() {
{pending.length > 0 && (
-
+
{pending.length} agenc{pending.length === 1 ? 'y' : 'ies'} awaiting your review
- setTab('agencies')} style={{ ...btn('ghost'), marginLeft: 'auto', borderColor: `${C.amber}55`, color: C.amber }}>Review
+ setTab('agencies')} style={{ ...btn('ghost'), marginLeft: 'auto', borderColor: tint(C.amber, 33), color: C.amber }}>Review
)}
- {loadErr &&
{loadErr}
}
+ {loadErr &&
{loadErr}
}
0 ? C.amber : undefined} />
diff --git a/packages/web/src/lib/color.ts b/packages/web/src/lib/color.ts
new file mode 100644
index 00000000..5dbdf6f2
--- /dev/null
+++ b/packages/web/src/lib/color.ts
@@ -0,0 +1,18 @@
+/**
+ * Translucent variants of a CSS color that may be a `var(--token)` reference
+ * rather than a literal hex.
+ *
+ * The obvious-looking `` `${color}18` `` , append a hex alpha byte , only works
+ * when `color` is a 6-digit hex literal. Every color in this app is a
+ * `var(--color-*)` token, so that idiom produced the literal string
+ * `"var(--color-accent)18"`: an invalid declaration the browser drops on the
+ * floor. The affected chips lost their background entirely and their
+ * brand-colored text landed on whatever surface was underneath, which on a
+ * `` was the brand gradient , brand-on-brand, unreadable.
+ *
+ * `color-mix` composes correctly against a custom property, so it is the only
+ * safe way to tint a token. scripts/css-contract-scan.ts bans the old idiom.
+ */
+export function tint(color: string, percent: number): string {
+ return `color-mix(in srgb, ${color} ${percent}%, transparent)`;
+}