Engineering
Frontend
Shared frontend foundations used by every ECC surface: component system, design tokens, state management, and routing conventions.
Stack
- Framework: React 19 + TanStack Start (SSR on the edge).
- Routing: TanStack Router with file-based routes in
src/routes/. - Data: TanStack Query + server functions; loaders prefetch, components
useSuspenseQuery. - Styling: Tailwind CSS v4 with semantic tokens in
src/styles.css. - Components: shadcn/ui primitives, extended with ECC variants.
- Forms: React Hook Form + Zod resolvers.
- Charts: Recharts for KPIs; deck.gl for geospatial overlays.
- Testing: Vitest (unit), Playwright (e2e), Storybook (visual).
Design system
All colors, radii, and typography are exposed as CSS variables and mapped to Tailwind utilities. Components never hard-code colors — they use bg-primary, text-muted-foreground, etc.
- Palette: climate green primary, neutral slate surfaces, signal colors for impact deltas.
- Type: Inter for UI, JetBrains Mono for tabular numerals and code.
- Spacing: 4 px base unit, 8 px rhythm in dense data views.
- Density:
comfortable(default),compact(analyst views),spacious(mobile). - Dark mode: first-class; tokens defined in
.darkwith matched contrast ratios.
Routing & data loading
// src/routes/_app/deals.$dealId.tsx
export const Route = createFileRoute('/_app/deals/$dealId')({
loader: ({ context, params }) =>
context.queryClient.ensureQueryData(dealQuery(params.dealId)),
component: DealDetail,
});
function DealDetail() {
const { dealId } = Route.useParams();
const { data } = useSuspenseQuery(dealQuery(dealId));
return <DealView deal={data} />;
}State management
- Server state: TanStack Query (single source of truth for API data).
- URL state: TanStack Router search params for filters, tabs, ranges.
- Local UI state:
useState/useReducer; Zustand only for cross-cutting UI (command palette, toaster). - Forms: React Hook Form; never store form values in global state.
Performance budget
| Metric | Target |
|---|---|
| LCP (p75) | < 2.0 s |
| INP (p75) | < 200 ms |
| JS shipped per route | < 180 KB gzipped |
| API p95 latency | < 400 ms |
Accessibility
Every component meets WCAG 2.2 AA. We enforce this with axe-core in CI, manual screen-reader passes on critical flows (deal approval, MRV sign-off, retirement), and keyboard-only navigation tests.