Skip to content

Commit 577cdbd

Browse files
Merge pull request #56 from codefrydev/ButByBit
But by bit
2 parents 20d75c5 + b7cfc1a commit 577cdbd

349 files changed

Lines changed: 7127 additions & 5408 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Google Material 3 (M3) Expressive Design Rules
2+
3+
> **MANDATE:** All UI components, pages, views, modals, cards, widgets, and styles in `web/` must strictly adhere to Google Material 3 (M3) Expressive Design principles. Arbitrary hex colors, harsh drop shadows, sharp rectangular interactive elements, and un-scaled typography are strictly prohibited.
4+
5+
---
6+
7+
## 1. Core Design Philosophy
8+
9+
Google Material 3 Expressive evolves Material Design into an emotional, tactile, and highly structured visual language:
10+
1. **Expressive Tone & Emotion**: UI is not merely functional; it conveys intent, hierarchy, and delight through deliberate color harmonies, organic shapes, and responsive physics.
11+
2. **Tonal Elevation over Drop Shadows**: Surfaces communicate depth through layered **Surface Containers** and tonal shifts rather than heavy, blurry drop shadows.
12+
3. **Shape as Hierarchy**: Curvature signals interactivity and role. High-curvature shapes (pills, squircles, `rounded-full`, `rounded-2xl`) create clear visual distinction between containers and action triggers.
13+
4. **Purposeful Motion**: Every transition is tactile, using spring-like physics and emphasized decelerations. Actions provide instant micro-feedback (`scale-[0.98]` press state).
14+
5. **Accessibility by Default**: High contrast ratios (WCAG AA/AAA), 48x48dp minimum touch targets, visible 2px offset focus rings, and full `prefers-reduced-motion` compliance.
15+
16+
---
17+
18+
## 2. Color System & Dynamic Tonal Palette
19+
20+
Never use arbitrary hex values or untyped colors. Always use M3 role-based semantic tokens:
21+
22+
### Primary, Secondary, and Tertiary Roles
23+
24+
| Token | CSS Variable | Purpose |
25+
|---|---|---|
26+
| **Primary** | `--md-sys-color-primary` | Key interactive actions, primary buttons, active indicator pills |
27+
| **On-Primary** | `--md-sys-color-on-primary` | Text and icons placed on top of Primary |
28+
| **Primary Container** | `--md-sys-color-primary-container` | High-prominence container surfaces needing emphasis without solid fill |
29+
| **On-Primary Container** | `--md-sys-color-on-primary-container` | Text and icons on Primary Container |
30+
| **Secondary** | `--md-sys-color-secondary` | Less prominent components, filter chips, secondary toggles |
31+
| **On-Secondary** | `--md-sys-color-on-secondary` | Text/icons on Secondary |
32+
| **Secondary Container** | `--md-sys-color-secondary-container` | Medium-emphasis containers, tonal buttons, active nav indicators |
33+
| **On-Secondary Container** | `--md-sys-color-on-secondary-container` | Text/icons on Secondary Container |
34+
| **Tertiary** | `--md-sys-color-tertiary` | **Expressive accent**: contrasting warm/vibrant hue for highlights, badges, AI insights |
35+
| **On-Tertiary** | `--md-sys-color-on-tertiary` | Text/icons on Tertiary |
36+
| **Tertiary Container** | `--md-sys-color-tertiary-container` | Expressive cards, special callouts, AI insight banners |
37+
| **On-Tertiary Container** | `--md-sys-color-on-tertiary-container` | Text/icons on Tertiary Container |
38+
| **Error** | `--md-sys-color-error` | Critical errors, destructive actions |
39+
| **Error Container** | `--md-sys-color-error-container` | Warning/error cards, danger banners |
40+
41+
### Tonal Surface Hierarchy
42+
43+
Do **not** use flat, monochromatic cards or arbitrary background shades. Layer depth using the 5-tier Surface Container system:
44+
45+
```
46+
┌────────────────────────────────────────────────────────┐
47+
│ Surface Container Highest (Dialogs, Menus, Modals) │
48+
│ ┌──────────────────────────────────────────────────┐ │
49+
│ │ Surface Container High (Floating Bars, Popovers) │ │
50+
│ │ ┌────────────────────────────────────────────┐ │ │
51+
│ │ │ Surface Container (Standard Cards, Sheets) │ │ │
52+
│ │ │ ┌──────────────────────────────────────┐ │ │ │
53+
│ │ │ │ Surface Container Low (Subtle Panels)│ │ │ │
54+
│ │ │ │ ┌────────────────────────────────┐ │ │ │ │
55+
│ │ │ │ │ Surface / Lowest (Canvas/Page) │ │ │ │ │
56+
```
57+
58+
- **`surface-container-lowest`**: Recessed areas, code editors, sunken background tracks.
59+
- **`surface-container-low`**: Structural sidebars, secondary grouping panels.
60+
- **`surface-container`**: Default standard cards, list rows, content panels.
61+
- **`surface-container-high`**: Elevated search bars, active tabs, floating headers.
62+
- **`surface-container-highest`**: Modals, dropdown menus, context popovers.
63+
64+
### State Layers
65+
66+
Interactive states must apply semi-transparent state overlays (rather than abruptly jumping color):
67+
- **Hover**: 8% opacity tint of the element's on-color
68+
- **Focus**: 12% opacity tint + 2px offset outline
69+
- **Press / Active**: 12% opacity tint + `scale-[0.98]` tactile dip
70+
- **Drag**: 16% opacity tint + Level 3 elevation
71+
72+
---
73+
74+
## 3. Expressive Geometry & Shape Scale
75+
76+
Material 3 Expressive pairs structured layouts with organic, rounded geometry:
77+
78+
| Shape Token | Radius | Allowed Components |
79+
|---|---|---|
80+
| **None** | `0px` (`rounded-none`) | Full-bleed screen dividers, edge-to-edge layout borders |
81+
| **Extra Small** | `4px` (`rounded-xs`) | Micro tags, dense table inline badges |
82+
| **Small** | `8px` (`rounded-sm`) | Code snippets, compact data chips, inner item blocks |
83+
| **Medium** | `12px` (`rounded-md`) | Form inputs, select dropdowns, segmented button items |
84+
| **Large** | `16px` (`rounded-lg` / `rounded-xl`) | Standard content cards, snackbars, sub-panels |
85+
| **Extra Large** | `24px``28px` (`rounded-2xl` / `rounded-3xl`) | Modal dialogs, floating action sheets, hero cards |
86+
| **Full (Pill)** | `9999px` (`rounded-full`) | **Buttons**, **Filter chips**, **Status badges**, **Search bars**, **Floating pills** |
87+
88+
### Shape Rules:
89+
- **Buttons must be Pill (`rounded-full`)**: Primary, secondary, tonal, and outline action buttons must use full pill curvature.
90+
- **Cards must be `rounded-2xl` (16px) or `rounded-3xl` (24px)**: Never use sharp, boxy 4px/8px corners for main UI cards.
91+
- **Badges & Chips must be Pill (`rounded-full`)**: Filter chips, status pills, and counter tags must be fully rounded.
92+
93+
---
94+
95+
## 4. Typography Scale & Hierarchy
96+
97+
Use the M3 15-step typography scale. All text must strictly map to one of these roles:
98+
99+
1. **Display (Large 57px, Medium 45px, Small 36px)**:
100+
- For hero KPI numbers, executive summary scores, and landing headlines.
101+
- Tracking: `-0.25px` to `-0.5px` (tight, expressive).
102+
2. **Headline (Large 32px, Medium 28px, Small 24px)**:
103+
- For page titles and primary view section headers.
104+
- Font weight: `font-semibold` or `font-bold`.
105+
3. **Title (Large 22px, Medium 16px, Small 14px)**:
106+
- For card headers, list section dividers, and modal titles.
107+
- Font weight: `font-semibold`.
108+
4. **Body (Large 16px, Medium 14px, Small 12px)**:
109+
- For descriptive copy, analysis paragraphs, and data cell content.
110+
- Line height: Generous (`leading-relaxed`), font weight: `font-normal`.
111+
5. **Label (Large 14px, Medium 12px, Small 11px)**:
112+
- For buttons, chip labels, table column headers, and form input labels.
113+
- Font weight: `font-medium`, tracking: `tracking-wide`.
114+
115+
---
116+
117+
## 5. Tonal Elevation & Surface Depth
118+
119+
- **Level 0 (0dp)**: Flat surface, no elevation (`shadow-none`).
120+
- **Level 1 (1dp)**: Subtle separation, Surface Container Low (`--elevation-1`).
121+
- **Level 2 (3dp)**: Standard elevated cards, Surface Container (`--elevation-2`).
122+
- **Level 3 (6dp)**: Floating bars, filter pills, dropdowns.
123+
- **Level 4 (8dp)**: Modal dialogs, navigation drawers (`--elevation-3`).
124+
- **Level 5 (12dp)**: Floating Action Buttons (FAB), drag previews.
125+
126+
*Rule:* Never apply dark, heavy CSS box shadows. Depth is communicated 90% by container tone and 10% by soft, ambient occlusion.
127+
128+
---
129+
130+
## 6. Motion & Spring Physics
131+
132+
Material 3 Expressive motion feels spring-like, physical, and alive:
133+
134+
### Easing Tokens
135+
- **Emphasized Decelerate**: `cubic-bezier(0.05, 0.7, 0.1, 1.0)` (elements entering screen or expanding)
136+
- **Emphasized Accelerate**: `cubic-bezier(0.3, 0, 0.8, 0.15)` (elements exiting screen)
137+
- **Standard Spring**: `cubic-bezier(0.2, 0, 0, 1)` (hover, toggle, state transitions)
138+
139+
### Durations
140+
- Micro-interactions (hover, focus, chip toggle): `150ms``200ms`
141+
- Medium transitions (sheet open, expand card): `250ms``350ms`
142+
- Large transitions (dialog open, page transition): `400ms``500ms`
143+
144+
### Interactive Tactile Feedback:
145+
- All interactive elements must include active press scaling: `active:scale-[0.98]` or `.press`.
146+
- Card hover states must lift smoothly with `transition-all duration-200 ease-out hover:-translate-y-0.5`.
147+
- Grids and lists must feature staggered reveal transitions (30ms–50ms stagger per child).
148+
- **Reduced Motion**: Always include `motion-reduce:transition-none motion-reduce:transform-none`.
149+
150+
---
151+
152+
## 7. Component Standards & Recipes
153+
154+
### Buttons
155+
- **Filled Button (Primary)**:
156+
`rounded-full bg-md-sys-primary text-md-sys-on-primary font-medium px-5 py-2.5 transition-all duration-200 hover:shadow-md active:scale-[0.98]`
157+
- **Filled Tonal Button (Medium emphasis)**:
158+
`rounded-full bg-md-sys-secondary-container text-md-sys-on-secondary-container font-medium px-5 py-2.5 transition-all hover:bg-opacity-90 active:scale-[0.98]`
159+
- **Outlined Button**:
160+
`rounded-full border border-md-sys-outline text-md-sys-primary font-medium px-5 py-2.5 transition-all hover:bg-md-sys-primary/8 active:scale-[0.98]`
161+
- **Text Button**:
162+
`rounded-full text-md-sys-primary font-medium px-3 py-2 transition-all hover:bg-md-sys-primary/8 active:scale-[0.98]`
163+
- **Floating Action Button (FAB)**:
164+
`rounded-2xl bg-md-sys-primary-container text-md-sys-on-primary-container p-4 shadow-lg hover:shadow-xl active:scale-[0.96]`
165+
166+
### Cards
167+
- Container: `bg-md-sys-surface-container rounded-2xl p-6 border border-md-sys-outline-variant/50 transition-all`
168+
- Clickable/Interactive Card: Add `hover:shadow-md hover:-translate-y-0.5 cursor-pointer active:scale-[0.99]`
169+
- **Mandatory Repository Rule**: Every report card and dashboard widget MUST wire `devData` on `<Card devData={...}>` (see `AGENT.md` § Dev widget JSON copy).
170+
171+
### Chips & Badges
172+
- Filter Chip: `rounded-full px-4 py-1.5 text-xs font-medium border border-md-sys-outline transition-all`
173+
- Selected Chip: `bg-md-sys-secondary-container text-md-sys-on-secondary-container border-transparent`
174+
- Status Badge: `rounded-full px-3 py-1 text-xs font-semibold inline-flex items-center gap-1.5`
175+
176+
### Form Controls & Inputs
177+
- Container: `bg-md-sys-surface-container-high rounded-xl border border-md-sys-outline-variant px-4 py-3 text-md-sys-on-surface`
178+
- Focus State: `focus:outline-none focus:ring-2 focus:ring-md-sys-primary focus:border-transparent`
179+
- Helper Text: `text-xs text-md-sys-on-surface-variant mt-1.5`
180+
181+
---
182+
183+
## 8. Developer & Agent Strict Checklist
184+
185+
Before committing any UI change in `web/`, verify each item:
186+
187+
- [ ] **Color Roles**: Are colors sourced from M3 role tokens (`md-sys-*`) instead of hardcoded hex colors?
188+
- [ ] **Surface Containers**: Is depth layered using `surface-container-*` rather than arbitrary background grays?
189+
- [ ] **Shape Curvature**: Are action buttons and chips pill-shaped (`rounded-full`)? Are cards `rounded-2xl` or `rounded-3xl`?
190+
- [ ] **Typography Scale**: Do text elements strictly follow Display / Headline / Title / Body / Label hierarchy?
191+
- [ ] **Tactile Press**: Do buttons and clickable cards have active press feedback (`active:scale-[0.98]` / `.press`)?
192+
- [ ] **Dev Widget Copy**: Does every card/widget pass `devData` to `<Card>` or render `<DevCopyJsonButton>`?
193+
- [ ] **Accessibility**: Does the touch target meet 48x48dp minimum? Does text contrast exceed 4.5:1? Is there a visible focus ring?
194+
- [ ] **Dark Mode**: Do all components render cleanly in both Light mode and `html.dark` mode?

.gitattributes

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
* text=auto
2+
3+
# Enforce LF for shell scripts and Linux container files
4+
*.sh text eol=lf
5+
*.bash text eol=lf
6+
*.conf text eol=lf
7+
Dockerfile* text eol=lf
8+
9+
# Windows PowerShell scripts
10+
*.ps1 text eol=crlf
11+
*.bat text eol=crlf
12+
*.cmd text eol=crlf

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ input.txt
2929
pipeline-config.txt
3030
*__pycache__*
3131
.coverage
32-
.agents/
32+
.agents/*
33+
!.agents/rules/
3334
skills-lock.json
3435
crawl_results.csv
3536
commit.*

AGENT.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ Developer reference for agents and contributors. User-facing overview: [README.m
6262

6363
Schema changes: add an EF Core migration (`dotnet ef migrations add <Name>` in `services/Schema/src/Schema.Model/`).
6464

65+
**UI Design — Google Material 3 (M3) Expressive Design (Strict Rules)**
66+
67+
All frontend UI code in `web/` must strictly comply with **Google Material 3 Expressive Design**. Canonical rules: [.agents/rules/m3-expressive-design.md](.agents/rules/m3-expressive-design.md).
68+
69+
| Element | M3 Expressive Rule | Allowed Tailwind / CSS |
70+
|---|---|---|
71+
| **Buttons** | **Must be pill-shaped (`rounded-full`)**. High emphasis uses Primary; medium emphasis uses Filled Tonal (`bg-secondary-container`). | `rounded-full px-5 py-2.5 font-medium transition-all active:scale-[0.98]` |
72+
| **Cards** | **Tonal Surface Container (`rounded-2xl` or `rounded-3xl`)**. Layer depth using `surface-container-*` hierarchy instead of arbitrary dark drop shadows. Mandatory `devData` wiring. | `bg-md-sys-surface-container rounded-2xl p-6 border border-md-sys-outline-variant/50` |
73+
| **Chips & Badges** | **Must be pill-shaped (`rounded-full`)**. Height 32dp (or compact 24dp), tonal background. | `rounded-full px-3.5 py-1 text-xs font-medium` |
74+
| **Typography** | Strictly follow M3 15-scale (Display, Headline, Title, Body, Label). Tighter tracking on display/headline; generous line-height on body. | M3 type scale roles (`Display`, `Headline`, `Title`, `Body`, `Label`) |
75+
| **Motion** | Responsive spring curves (`cubic-bezier(0.2, 0, 0, 1)`), tactile press downscale (`active:scale-[0.98]` / `.press`), staggered entrance lists. | `transition-all duration-200 ease-out active:scale-[0.98]` |
76+
| **Elevation** | Surface depth communicated through **tonal color shifts** (Surface Container Lowest to Highest), not heavy drop shadows. | `--elevation-1` to `--elevation-3` |
77+
| **Accessibility** | Minimum 48x48dp touch targets, ≥4.5:1 text contrast, visible 2px offset focus rings, full `prefers-reduced-motion` support. | `focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2` |
78+
6579
**Charts — Chart.js + D3 (hybrid)**
6680

6781
The web UI uses **both** Chart.js and D3.js. Pick the library that fits each chart; do not migrate everything to one stack.

AGENTS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,15 @@ python -m src # Run audit pipeline
5050
| Report/card widgets (dev JSON copy) | `Card` `devData` prop — see [AGENT.md](AGENT.md) § Dev widget JSON copy; reference: `web/src/components/overview/OverviewExecutiveSummary.tsx` |
5151
| Charts | D3: `web/src/components/charts/d3/`, `web/src/lib/viz/` · Chart.js: GSC/GA4/Links etc. — see [AGENT.md](AGENT.md) § Charts |
5252

53+
**Google Material 3 (M3) Expressive Design (Strict UI Rules):** All UI components, pages, views, cards, modals, and styling in `web/` **must strictly follow Google Material 3 Expressive Design** — full specification in [.agents/rules/m3-expressive-design.md](.agents/rules/m3-expressive-design.md).
54+
- **Colors & Surfaces:** Use M3 semantic tokens (`md-sys-color-*`) and the 5-tier Surface Container system (`surface-container-lowest` through `highest`) for tonal elevation. No arbitrary hex values or harsh drop shadows.
55+
- **Shapes:** Action buttons, filter chips, and status badges **must be pill-shaped** (`rounded-full`); cards must use expressive curvature (`rounded-2xl` or `rounded-3xl`).
56+
- **Typography:** Strictly adhere to the 15-tier M3 typography scale (Display, Headline, Title, Body, Label).
57+
- **Motion & Feedback:** Include tactile press scaling (`active:scale-[0.98]` / `.press`), spring physics, and full `prefers-reduced-motion` compliance.
58+
5359
**Charts:** Use **both** Chart.js and D3 — choose per chart (Overview/Compare → D3; standard GSC/GA4 bars → Chart.js). Full rules in [AGENT.md](AGENT.md).
5460

5561
**Dev widget JSON copy:** In local dev, each report card/panel should pass `devData` on `Card` so agents/devs can copy the widget’s JSON from the top-right `{ }` button. Wire on every widget you add or touch; full conventions in [AGENT.md](AGENT.md) § Dev widget JSON copy.
5662

5763
**Common pitfalls:** See [AGENT.md](AGENT.md) for the full footguns checklist (React context, Python local imports, psycopg dict rows, coverage gates).
64+

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ COPY docker-entrypoint.sh /app/docker-entrypoint.sh
6666
ENV NODE_ENV=production
6767

6868
# Persisted data directory (secrets + shadow config)
69-
RUN mkdir -p /data && chmod +x /app/docker-entrypoint.sh
69+
RUN mkdir -p /data \
70+
&& sed -i 's/\r$//' /app/docker-entrypoint.sh \
71+
&& chmod +x /app/docker-entrypoint.sh
7072

7173
EXPOSE 8096
7274

local-prod.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Wrapper — run from repo root: .\local-prod.ps1 [command]
2+
& "$PSScriptRoot\scripts\local-prod.ps1" @args

0 commit comments

Comments
 (0)