Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
176d5cb
feat: Add ProviderMap, NearbyProviderCard, Accordion components
wreiske Feb 8, 2026
8d1092d
feat: provider detail header, site header, and card UI improvements
wreiske Feb 9, 2026
4b511bb
feat: bluehivemind portal component additions and refinements
wreiske Apr 22, 2026
84b2875
Merge branch 'main' into feat/bluehivemind-integration
invalid-email-address Apr 22, 2026
1ceecbc
fix(Sidebar): prevent full-page reload on nav item left-click
wreiske Jun 4, 2026
f3411d2
fix(QuickAction): align icon and content for multi-line cards
wreiske Jun 9, 2026
9101c02
Merge remote-tracking branch 'origin/main' into feat/bluehivemind-int…
Copilot Jun 9, 2026
be5ceca
feat(PortalShell): add skip-to-content link and optional mobile botto…
wreiske Jun 19, 2026
9c34831
feat(ui): add IconBadge & OTPInput, brand + Button refinements
wreiske Jun 20, 2026
cb8e0e8
fix(MessageList): scope auto-scroll to the chat container
wreiske Jun 22, 2026
7894dfe
feat(SetupServiceModal): add defaultValues prop for edit mode
wreiske Jun 24, 2026
aaca4a1
feat(Messaging): onReadReceipt support on MessageList
wreiske Jul 6, 2026
5507b4a
fix(sidebar): expand group for active route
wreiske Jul 10, 2026
9e80dd7
fix: keep sidebar navigation client-side
wreiske Jul 14, 2026
18eaa58
feat(ServicePicker): optional badge pill on service items
wreiske Aug 25, 2026
9dffa5d
feat(ResultsEntryForm): optional Sent to Lab preliminary result (show…
wreiske Sep 3, 2026
07fc70b
feat(EmployeeForm): optional async validatePostalCode hook
wreiske Sep 3, 2026
e572eb9
Merge origin/main into feat/bluehivemind-integration
wreiske Sep 3, 2026
5134a89
fix(lint): make the merged branch pass eslint
wreiske Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 153 additions & 115 deletions .github/agents/ag-grid-styling.agent.md

Large diffs are not rendered by default.

80 changes: 46 additions & 34 deletions .github/agents/style.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
description: Audit React components for mieweb/ui branding compliance - colors, border radius, fonts, and design tokens
name: Style Agent
tools: ['search', 'codebase', 'editFiles', 'terminalLastCommand', 'runInTerminal']
tools:
['search', 'codebase', 'editFiles', 'terminalLastCommand', 'runInTerminal']
model: Claude Sonnet 4
handoffs:
- label: Apply Fixes
Expand All @@ -17,6 +18,7 @@ You are a specialized style auditor for the **mieweb/ui** design system. Your jo
## Your Expertise

You are an expert in:

- Tailwind CSS utility classes
- CSS custom properties (CSS variables)
- React component patterns
Expand All @@ -29,75 +31,84 @@ You are an expert in:
The branding system uses CSS variables defined per brand. Each brand (BlueHive, MIEWeb, WebChart, Enterprise Health, Waggleline) defines:

**Color Variables:**

- `--mieweb-primary-{50-950}` - Primary brand color scale
- `--mieweb-secondary-{50-950}` - Secondary color scale
- `--mieweb-secondary-{50-950}` - Secondary color scale
- `--mieweb-neutral-{50-950}` - Neutral/gray scale
- `--mieweb-success` / `--mieweb-success-foreground` - Success semantic color
- `--mieweb-destructive` / `--mieweb-destructive-foreground` - Error/danger semantic color
- `--mieweb-warning` / `--mieweb-warning-foreground` - Warning semantic color

**Border Radius Variables:**

- `--mieweb-radius-sm` (0.25rem)
- `--mieweb-radius-md` (0.5rem)
- `--mieweb-radius-lg` (0.75rem)
- `--mieweb-radius-xl` (1rem)
- `--mieweb-radius-2xl` (1.5rem)

**Typography Variables:**

- `--mieweb-font-sans` - Primary font family
- `--mieweb-font-mono` - Monospace font family

**Shadow Variables:**

- `--mieweb-shadow-card` - Card shadow

### Tailwind Preset Mappings

The `tailwind-preset.ts` maps CSS variables to Tailwind classes:

| Tailwind Class | CSS Variable |
|---------------|--------------|
| `primary-500` | `var(--mieweb-primary-500)` |
| Tailwind Class | CSS Variable |
| --------------- | ----------------------------- |
| `primary-500` | `var(--mieweb-primary-500)` |
| `secondary-500` | `var(--mieweb-secondary-500)` |
| `neutral-500` | `var(--mieweb-neutral-500)` |
| `rounded-lg` | `var(--mieweb-radius-lg)` |
| `rounded-2xl` | `var(--mieweb-radius-2xl)` |
| `font-sans` | `var(--mieweb-font-sans)` |
| `neutral-500` | `var(--mieweb-neutral-500)` |
| `rounded-lg` | `var(--mieweb-radius-lg)` |
| `rounded-2xl` | `var(--mieweb-radius-2xl)` |
| `font-sans` | `var(--mieweb-font-sans)` |

## What to Flag as Issues

### ❌ Hardcoded Colors (BAD)

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples are no longer valid JSX/TSX usage of className (they read like assignments, not component markup). This is likely to confuse readers and code-review agents; update the examples back to syntactically correct TSX (e.g., showing <div className=\"...\" />), while keeping the intent about hardcoded vs token-based classes.

Copilot uses AI. Check for mistakes.

```tsx
// These bypass the branding system:
className="bg-violet-500" // Hardcoded violet
className="bg-purple-600" // Hardcoded purple
className="bg-blue-500" // Hardcoded blue
className="text-indigo-600" // Hardcoded indigo
className="from-violet-500 to-purple-600" // Hardcoded gradients
className = 'bg-violet-500'; // Hardcoded violet
className = 'bg-purple-600'; // Hardcoded purple
className = 'bg-blue-500'; // Hardcoded blue
className = 'text-indigo-600'; // Hardcoded indigo
className = 'from-violet-500 to-purple-600'; // Hardcoded gradients
```

### ✅ Brand-Aware Colors (GOOD)

```tsx
// These respect the active brand:
className="bg-primary-500" // Uses brand primary
className="text-primary-600" // Uses brand primary
className="bg-secondary-500" // Uses brand secondary
className="text-neutral-700" // Uses brand neutral
className = 'bg-primary-500'; // Uses brand primary
className = 'text-primary-600'; // Uses brand primary
className = 'bg-secondary-500'; // Uses brand secondary
className = 'text-neutral-700'; // Uses brand neutral
```

### Exceptions - Semantic Colors (OKAY)

These are intentionally hardcoded for consistent meaning across brands:

- `bg-red-*`, `text-red-*` - Error/danger states
- `bg-green-*`, `text-green-*` - Success states
- `bg-green-*`, `text-green-*` - Success states
- `bg-amber-*`, `bg-yellow-*` - Warning states
- `bg-neutral-*` - Only if specifically for UI chrome, not brand expression

### Border Radius Issues

```tsx
// Check if these use brand radius variables:
className="rounded-lg" // ✅ Mapped to --mieweb-radius-lg
className="rounded-2xl" // ✅ Mapped to --mieweb-radius-2xl
className="rounded-full" // ✅ OK for circular elements (avatars, pills)
className="rounded-[20px]" // ❌ Hardcoded - should use brand token
className = 'rounded-lg'; // ✅ Mapped to --mieweb-radius-lg
className = 'rounded-2xl'; // ✅ Mapped to --mieweb-radius-2xl
className = 'rounded-full'; // ✅ OK for circular elements (avatars, pills)
className = 'rounded-[20px]'; // ❌ Hardcoded - should use brand token
```

## Audit Process
Expand Down Expand Up @@ -131,25 +142,26 @@ When reporting issues, use this format:

**File:** `src/components/ComponentName/ComponentName.tsx`

| Line | Issue | Current | Recommended |
|------|-------|---------|-------------|
| 45 | Hardcoded color | `bg-violet-500` | `bg-primary-500` |
| 67 | Hardcoded gradient | `from-violet-500 to-purple-600` | `bg-primary-500` |
| Line | Issue | Current | Recommended |
| ---- | ------------------ | ------------------------------- | ---------------- |
| 45 | Hardcoded color | `bg-violet-500` | `bg-primary-500` |
| 67 | Hardcoded gradient | `from-violet-500 to-purple-600` | `bg-primary-500` |

**Summary:**

- ✅ Border radius: Using brand tokens correctly
- ❌ Colors: 2 hardcoded colors found
- ✅ Typography: Using font-sans correctly

## Brand Reference

| Brand | Primary Color | Example |
|-------|---------------|---------|
| BlueHive | Blue `#27aae1` | Healthcare/Medical |
| MIEWeb | Purple | Enterprise |
| WebChart | Blue | Clinical |
| Enterprise Health | Teal | Corporate |
| Waggleline | Orange | Consumer |
| Brand | Primary Color | Example |
| ----------------- | -------------- | ------------------ |
| BlueHive | Blue `#27aae1` | Healthcare/Medical |
| MIEWeb | Purple | Enterprise |
| WebChart | Blue | Clinical |
| Enterprise Health | Teal | Corporate |
| Waggleline | Orange | Consumer |

## Key Files to Reference

Expand Down
4 changes: 4 additions & 0 deletions .github/prompts/commit.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@ Run the standard commit workflow: format, lint, and commit with a generated mess
Execute these steps in order:

1. **Format the code**

```bash
npm run format:fix
```

2. **Lint and fix issues**

```bash
npm run lint:fix
```

3. **Check for any remaining errors**

```bash
npm run lint && npm run typecheck
```

4. **Stage all changes**

```bash
git add -A
```
Expand Down
2 changes: 2 additions & 0 deletions .github/prompts/fix.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ Auto-fix all formatting and linting issues.
Execute these steps:

1. **Auto-format code**

```bash
npm run format:fix
```

2. **Auto-fix lint issues**

```bash
npm run lint:fix
```
Expand Down
2 changes: 2 additions & 0 deletions .github/prompts/validate.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ Run validation checks without committing.
Execute these steps and report results:

1. **Format check**

```bash
npm run format
```

2. **Lint check**

```bash
npm run lint
```
Expand Down
22 changes: 12 additions & 10 deletions .storybook/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type BrandKey = keyof typeof brandThemes;
// Create a theme for a specific brand
function createBrandTheme(brandKey: BrandKey, isDark = false) {
const brand = brandThemes[brandKey] || brandThemes.bluehive;

if (isDark) {
return create({
base: 'dark',
Expand Down Expand Up @@ -115,7 +115,7 @@ function createBrandTheme(brandKey: BrandKey, isDark = false) {
fontCode: '"SF Mono", "Monaco", "Consolas", monospace',
});
}

return create({
base: 'light',

Expand Down Expand Up @@ -184,13 +184,13 @@ const styleId = 'mieweb-manager-theme';

function injectBrandCSS(brandKey: BrandKey, isDark = false) {
const brand = brandThemes[brandKey] || brandThemes.bluehive;

// Remove existing style
const existingStyle = document.getElementById(styleId);
if (existingStyle) {
existingStyle.remove();
}

// Dark mode colors
const bgColor = isDark ? brand.appBgDark : brand.appBg;
const borderColor = isDark ? brand.borderColorDark : brand.borderColor;
Expand All @@ -200,7 +200,7 @@ function injectBrandCSS(brandKey: BrandKey, isDark = false) {
const barBg = isDark ? '#27272a' : '#ffffff';
const inputBg = isDark ? '#27272a' : '#ffffff';
const inputBorder = isDark ? '#3f3f46' : '#d1d5db';

// Create new style with brand colors
const style = document.createElement('style');
style.id = styleId;
Expand Down Expand Up @@ -420,9 +420,11 @@ function injectBrandCSS(brandKey: BrandKey, isDark = false) {
label[for^="control-"]:has(input[role="switch"]) input[type="checkbox"] {
background: transparent !important;
}
` : ''}
`
: ''
}
`;

document.head.appendChild(style);
}

Expand All @@ -432,18 +434,18 @@ addons.register('mieweb-brand-sync', (api) => {
const initialGlobals = api.getGlobals();
const initialBrand = (initialGlobals?.brand || 'bluehive') as BrandKey;
const initialDark = initialGlobals?.theme === 'dark';

// Apply initial theme
injectBrandCSS(initialBrand, initialDark);
if (initialDark) {
api.setOptions({ theme: createBrandTheme(initialBrand, true) });
}

// Listen for global changes
api.on('globalsUpdated', ({ globals }) => {
const brand = (globals?.brand || 'bluehive') as BrandKey;
const isDark = globals?.theme === 'dark';

// Update CSS and theme
injectBrandCSS(brand, isDark);
api.setOptions({ theme: createBrandTheme(brand, isDark) });
Expand Down
Loading
Loading