# Phase 3 — Frontend experience (frontend-design + UI/UX agent showcase)

Built by the **frontend implementer agent** under the frontend-design skill. Must follow
project conventions: Svelte 5 runes, `ToggleSwitch` for booleans, `ConfirmDialog` for the
sync action, `$t` with **en+ru parity**, the `.panel` vocabulary from `DeployHistoryPanel`.

## Tasks

- [ ] **`web/src/lib/api.ts`**: `GitOpsStatus` + `DriftEntry` interfaces; `fetchWorkloadGitOps(id)`,
  `fetchWorkloadDrift(id)`, `syncWorkloadGitOps(id)`, `setWorkloadGitOps(id, {enabled, path})`
  following the existing `get<T>`/`post<T>` typed-fetcher pattern (mirror `fetchWorkloadDeploys`).
- [ ] **`GitOpsPanel.svelte`** (mounted on `apps/[id]` near the other panels): the
  centerpiece. Sections:
  - Header: title + status pill (`synced` / `N changes` / `no file` / `fetch failed`) +
    last-sync/commit meta + enable/disable `ToggleSwitch`.
  - **Drift view** — the design focus. For each declared field show repo-value vs
    live-value with a clean/changed state. Distinctive, legible, on-brand (forge tokens,
    `--forge-mono`, the `--color-warning`/`--color-success` hues already used). No diff
    library exists — design a purpose-built field-level diff (NOT a generic `<pre>` dump).
  - Rendered `.tinyforge.yml` preview (the `.code-area`/editor frame vocabulary).
  - "Sync now" button → `ConfirmDialog` ("apply repo config to live") → `syncWorkloadGitOps`
    → toast + refresh. Admin-only affordance.
  - `no_file` / `fetch_failed` empty states (clear, not alarming).
- [ ] **GitOps-managed badge** on apps list rows (`apps/+page.svelte`, only dockerfile/static)
  and the detail hero — reuse the `.badge` chip vocabulary.
- [ ] **Read-only gate** on the source-config edit form: when managed, lock exactly the
  fields the synced overlay declares (derive from the drift/parsed payload) + a banner
  ("managed by `.tinyforge.yml` — edit the file and sync").
- [ ] **i18n**: `apps.detail.gitops.*` in BOTH `en.json` and `ru.json` (verify parity).

## Verify

- `npm run check` (0 errors), `npm run build`, `npm run test` green; i18n key parity equal.
- Restart dev server (`./scripts/dev-server.sh`).

## Handoff notes

_(filled after implementation)_
