User feedback: only the date+time matters. No override toggle, no
"overridden" badge, no UTC/local-time conversion. What you type is what
gets stored is what you see.
- Removed the `override` state, the checkbox label, the conditional show
of the input, and the "auto-stamped at" hint.
- Single always-on datetime-local input under the "Executed at" label,
disabled only while the test is `pending` (backend rejects timestamp
writes until the state machine reaches executed/reviewed_by_blue).
- `isoToInputValue` and `inputValueToIso` now strip/append the time
segment verbatim — `iso.slice(0, 16)` and `${local}:00Z`. No more
round-trip through `new Date(...).toISOString()` that pulled values
through the browser's local TZ.
- Any edit of the input is implicitly an override at submit time
(`executed_at_overridden = true` if non-empty). The flag is purely
internal bookkeeping — never surfaced in the UI per user request.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Metamorph frontend
Vite + React 18 + TypeScript + TailwindCSS. Design tokens from ../tasks/design.md are in tailwind.config.ts.
Local dev
npm install
npm run dev # http://localhost:5173 (proxies /api/* to http://localhost:8000)
Build
npm run build # outputs to dist/
npm run preview # serves dist/ on http://localhost:8080
Quality
npm run typecheck
npm run lint
npm run format
Layout
src/
├── App.tsx # M0 home page (health check + design tokens demo)
├── main.tsx
├── index.css # Tailwind base + tinted-accent utilities
├── components/ui/ # RTOps design primitives: Card, Tag, SectionHeader, FlowNode, Button
├── lib/
│ ├── api.ts # fetch wrapper (M2 will replace with auth-aware client)
│ └── cn.ts # classnames + ACCENTS palette
└── vite-env.d.ts