← all branches

feat/energia-ux

needs attentionviewing older commit
bf33cdf · fullPR #301reviewed 2026-07-11 06:02 UTC2H · 6M · 6L · 5I
The branch
Purpose
Design/UX exploration for a new Energía enterprise energy management module serving multi-site Mexican companies billed by CFE
Goal
Produce a 7-screen minimal prototype + JTBD map + design principles to validate the UX direction before implementation
Sub-goals
  • SG-1: Establish psychology-of-design principles (one anchor/screen, loss framing, progressive disclosure, Hick's Law)
  • SG-2: Ground screen designs in a rigorous JTBD map covering Finance, FP&A, Operations, Procurement, ESG, and Executive stakeholders
  • SG-3: Document detector verdict ledger — kill false-positive bill-audit detectors before they reach customers
  • SG-4: Build 7-screen HTML prototype from a shared design system (ds.css) assembled by a build script
The changes (whole branch)
What
Added 15 new files under docs/design/: 3 design/research docs (principles, JTBD map, detector ledger), a screen-builder CONTRACT, a Node.js assembler script, a shared CSS design system, an app shell, 7 HTML screen fragments, and the assembled output
Why
Validate UX direction for a corporate energy management platform (Energía module) before committing engineering resources; establish shared design vocabulary and screen specification for agent-assisted parallel screen construction
Areas
docs/design/ (design docs)+6040docs/design/energia-prototype/ (build infra: assembler, CSS, shell)+3220docs/design/energia-prototype/screens/ (7 screen fragments)+14350docs/design/energia-prototype/energia-platform-full.html (assembled output)+17350
Blast
15 new files, +4096 lines, all under docs/design/ — zero production code, zero schema changes, zero TypeScript. No blast radius on the running platform.
design-only no-production-code new-directory-pattern
typecheck· no TypeScript in this branchtests· no test files in this branchCI checks· CI check API not accessible via tokencoderabbit· no .coderabbit.yaml in repo

Findings · 17

correctness4

medium

CONTRACT.md prose says 'Six screens' but 7 are specified and built

docs/design/energia-prototype/CONTRACT.md:3

Line 3: 'Six screens are built in parallel by different agents.' The screen list in the same file and assemble.mjs both enumerate 7 screens (portfolio, findings, budget, payments, site, carbon, sites). Off-by-one in the prose will confuse future agents reading the contract.

medium

Assembled output renders in quirks mode — missing DOCTYPE, html, head, body

docs/design/energia-prototype/energia-platform-full.html:1

shell.html has no `<!DOCTYPE html>`, `<html>`, `<head>`, or `<body>` tags. The assembled file opens directly with `<title>`. Browsers fall back to quirks mode, which alters box-model behaviour and can break CSS custom property inheritance. Fix: wrap shell.html in `<!DOCTYPE html><html lang='es-MX'><head>…</head><body>…</body></html>`.

low

JTBD §3 lists 17 product screens; prototype covers 7 — selection rationale undocumented

docs/design/energia-jtbd-map.md:301

The JTBD map's §3 enumerates 17 distinct screens as the full product vision. The 7 prototype screens are a chosen subset but neither document explains the selection criteria or maps prototype slugs to JTBD screen numbers. A comment in CONTRACT.md cross-referencing the JTBD would prevent scope confusion.

low

`h2.sect` listed in CONTRACT.md allowed classes but not defined in ds.css

docs/design/energia-prototype/ds.css

CONTRACT.md rule 2 lists `h2.sect` as a composable class. Grepping ds.css for `.sect` returns no match. Screens that use `<h2 class='sect'>` receive plain unstyled `<h2>` rendering instead of the expected section-header treatment.

security2

low

Real brand name (Grupo Axo) used as persona with fabricated financials in committed prototype

docs/design/energia-prototype/shell.html

The prototype uses Grupo Axo (a real Mexican retailer) as the illustrative client, with invented but plausible figures ($45.26M MXN annual spend, $1.55M savings). No real PII or credentials present; repo is private and the UI labels it 'maqueta · datos ilustrativos'. Low risk as-is, but if the repo ever goes public this could be misread as disclosing a real engagement.

info

Static HTML prototype — no external requests, no XSS vectors, no credentials

docs/design/energia-prototype/

All security checks passed: zero external CDN/network URLs, no innerHTML/eval/document.write, all JS uses classList and setAttribute with hardcoded values, assemble.mjs reads from a fixed array with no path traversal, no real PII or credentials. The prototype is clean.

conventions3

medium

Generated artifact `energia-platform-full.html` committed without gitignore entry

docs/design/energia-prototype/energia-platform-full.html

assemble.mjs writes this file as its output. No .gitignore entry exists for it. If a screen is edited without re-running the assembler, the committed output silently drifts from the sources. If committed intentionally as a shareable snapshot, add a `<!-- generated by assemble.mjs -->` header comment and document in CONTRACT.md.

low

Prototype token vocabulary (`--spend`, `--value`, `--ink`) undocumented as distinct from platform tokens

docs/design/energia-prototype/ds.css:1

Platform tokens use Shadcn/Radix semantics (`--primary`, `--accent`, `--card`). The prototype intentionally uses a different grammar and reserves green differently. CONTRACT.md should note that ds.css is NOT a 1:1 port to the platform — otherwise an implementer might assume the classes translate directly.

info

Design docs in English — appropriate for internal engineering/design artifacts

docs/design/energia-jtbd-map.md

CLAUDE.md's Spanish (es-MX) requirement applies to the marketing website (apps/web). Internal design/research docs in English are consistent with the project convention for developer communication. No issue.

tests2

low

No script or CI step to verify assemble.mjs runs clean after screen edits

docs/design/energia-prototype/assemble.mjs

assemble.mjs must be run manually; no package.json script or workflow invokes it. The built-in guards (ID check, style/script count) are good, but without a CI trigger the committed energia-platform-full.html can drift from sources silently. A one-liner npm script would make verification trivial.

info

assemble.mjs built-in guards are adequate — self-testing script

docs/design/energia-prototype/assemble.mjs:13

The script validates all 7 screen IDs, asserts exactly 1 `<style>` and 1 `<script>` in output, and throws loudly on violations. For a design prototype build tool, this is sufficient test coverage.

improvement6

high

Mobile nav hidden below 940px with no fallback — prototype unusable on tablet/phone

docs/design/energia-prototype/ds.css:237

`.side{display:none}` at 940px removes the entire sidebar with zero replacement — no hamburger, no bottom tab bar, no drawer. Every screen becomes inaccessible since screen-switching is sidebar-only. A sticky bottom tab strip with the 4 primary nav items would satisfy Hick's Law and fix the dead-end.

high

`fp_chronic_penalty` finding tagged 'Error CFE' with green — violates color grammar and detector taxonomy

docs/design/energia-prototype/screens/findings.html:165

The FP-penalty finding (FP 0.82, CEDIS Toluca) uses `<span class='tag cfe'>Error CFE</span>` and green coloring. Per the detector ledger, `fp_chronic_penalty` is Category B — operational (client action), not a recoverable CFE billing error. Green is reserved strictly for value Batu recovers. This misleads Finance users into thinking CFE owes them money. Correct tag: `.tag.ops` ('Optimización').

medium

`.stats` and `.statgrid` are near-duplicate — `.stats .cell` is undefined, used in site.html

docs/design/energia-prototype/ds.css:122

Both classes share identical grid, gap, and s-v/s-l typography. The only difference is `.statgrid .cell` adds background/padding resets. `screens/site.html` uses `.stats > .cell` children whose styling is never defined. Merge into one component or explicitly define `.stats .cell` to avoid accidental layout dependency.

medium

Carbon screen missing market-based Scope 2 figure — JTBD §4 item 14 unmet

docs/design/energia-prototype/screens/carbon.html:9

JTBD requires dual Scope 2 display: location-based and market-based side by side. The screen shows only the location-based anchor and mentions market-based only as a grey sub-caption with no number. For the IFRS S2 demo use-case, even a 'market-based: N/D — sin CELs' secondary stat would satisfy the dual-method requirement that is the prototype's stated differentiator.

medium

Green (`--value`) applied to CFE error count in portfolio — color grammar violation

docs/design/energia-prototype/screens/portfolio.html:42

`<div class='k-v' style='color:var(--value)'>14</div>` colors the count '14 Errores de CFE' in green. Color grammar (CONTRACT.md rule 3, ds.css header) reserves green strictly for value Batu recovers — not for unresolved open findings. A user scanning quickly reads '14 (green)' as something completed/positive. Use `--ink` or `--warn` instead.

low

`energia-detector-ledger.md` misplaced in docs/design/ — it is an engineering product decision artifact

docs/design/energia-detector-ledger.md:1

The ledger records corpus backtesting verdicts with XML field references (`LECT_MANUAL`, `CANT_MED_RET`), sample counts, and kill/ship decisions for bill-audit detectors. This is engineering-facing, not UX-facing. Engineers working on domains/utility/ would not naturally look in docs/design/. Better home: docs/architecture/ or a pointer from the domain CLAUDE.md.

History · 4 commits

  1. 58f9af0safeincremental0H · 0M · 0L2026-07-16 13:48
  2. 661a293needs attentionincremental1H · 2M · 4L2026-07-16 13:30
  3. 935ca3dneeds attentionincremental5H · 7M · 4L2026-07-11 13:00
  4. bf33cdfneeds attentionfull2H · 6M · 6L2026-07-11 06:02current