# Feedmill Recounter — Web UI Redesign > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Redesign the feedmill_recounter web UI from a basic dark theme to a clean, modern, user-friendly interface with live preview of processing, using a Flat Design system with teal primary (#0D9488), orange accent (#EA580C), Plus Jakarta Sans font, and dark-mode-ready tokens. **Current State:** 4 templates (base.html, index.html, status.html, jobs.html), 1 CSS file (34 lines), no JS file. App.py serves on port 9000. **Tech Stack:** HTML, CSS, vanilla JS (no new Python dependencies), Flask templates --- ## Global Constraints - Python >= 3.10 (uses `X | Y` union syntax) - No new Python dependencies for UI redesign (Flask + OpenCV already installed) - Web UI port 9000 via `WEB_PORT` env variable - All model weights in `models/` directory; `.engine` files are gitignored - Class filtering by name string (`"sack"`, `"box"`, `"truck"`), not numeric ID - CSS uses Flat Design with teal primary (#0D9488), orange accent (#EA580C) - Font: Plus Jakarta Sans (Google Fonts CDN) - Dark-mode-ready CSS custom properties (light mode default, easy dark swap) - Accessible: skip-link, focus rings, semantic HTML, ARIA where needed - Responsive: mobile-first, works on 320px to 1920px+ - No JS frameworks — vanilla JS only - Live preview: pipeline emits JPEG frame every Nth frame → Job.latest_frame → served as base64 in API → JS polls and displays --- ## File Structure (changes only) ``` feedmill_recounter/ ├── static/ │ ├── style.css # REWRITE — full Flat Design system │ └── app.js # CREATE — JS for drag-drop, polling, preview ├── templates/ │ ├── base.html # REWRITE — semantic HTML, skip-link, font, tokens │ ├── index.html # REWRITE — drag-drop upload, model cards │ ├── status.html # REWRITE — progress bar, live preview, result cards │ └── jobs.html # REWRITE — card grid with badges + thumbnails ├── src/ │ ├── preview.py # CREATE — extract_thumbnail, probe_video, extract_sample_frames │ ├── pipeline.py # MODIFY — emit frame JPEG every Nth frame to job.latest_frame │ └── job.py # MODIFY — add latest_frame: bytes | None field └── app.py # MODIFY — add /preview/thumb, /api/jobs//samples, /api/jobs//frame routes ``` --- ### Task 1: Design System Foundation **Files:** - Rewrite: `feedmill_recounter/static/style.css` - Rewrite: `feedmill_recounter/templates/base.html` **Requirements:** 1. `style.css` — complete rewrite with: - CSS custom properties (design tokens) for colors, spacing, typography, radii, shadows - Teal primary: `--color-primary: #0D9488` (with 50-900 scale shades) - Orange accent: `--color-accent: #EA580C` (with 50-900 scale shades) - Neutrals: `--color-neutral-50` through `--color-neutral-900` - Status colors: success (#16A34A), warning (#F59E0B), error (#DC2626), info (#0EA5E9) - Typography: `--font-sans: 'Plus Jakarta Sans', system-ui, sans-serif` - Spacing scale: `--space-1` (4px) through `--space-16` (64px) - Border radius: `--radius-sm` (6px), `--radius-md` (8px), `--radius-lg` (12px), `--radius-xl` (16px) - Shadows: `--shadow-sm`, `--shadow-md`, `--shadow-lg` - Transitions: `--transition-fast` (150ms), `--transition-normal` (250ms) - Base reset/normalize - `.container` max-width 1200px centered - Skip-link (visually hidden, visible on focus) - Focus ring: 2px solid primary, offset 2px - Button styles: primary (teal), secondary (outline), accent (orange), ghost - Card component: `.card` with padding, border-radius, shadow, border - Badge component: `.badge` with status variants - Form elements: inputs, selects, labels with consistent styling - Responsive breakpoints: 640px, 768px, 1024px, 1280px 2. `base.html` — rewrite with: - ``, `` - ``, `` - Google Fonts link for Plus Jakarta Sans (weights 400, 500, 600, 700) - Skip-link: `` - Semantic `
` with `