# ChicoryTV UI Redesign — Visual Direction Brief (Pass 1) **Date:** 2026-07-01 **Issue:** [ersatztv#59 — full UI redesign and ChicoryTV rebrand](http://192.168.1.95:3000/timothy/ersatztv/issues/59) **Status:** Design direction locked; this brief drives the first Claude Design pass. > Scope of *this* document: the **visual-direction brief** for Pass 1 — the decisions plus the exact prompts to paste into Claude Design (claude.ai/design) to generate 4 hero screens. It is **not** the full #59 implementation spec. That comes after a look is locked. --- ## 1. Context & goals ErsatzTV is a custom IPTV channel server (C#/.NET 10, currently a Blazor Server + MudBlazor UI, ~60 Razor pages). The current UI is utilitarian ("Sonarr-like") and was never designed. Issue #59 calls for a complete redesign built **around the REST API** rather than legacy page patterns, plus a rename to **ChicoryTV**, with drag-and-drop workflows, better creation defaults/templates, and discoverable-but-not-heavy advanced config. **Goals (from #59):** - Slick, modern, app-like UI built around the API. - Drag-and-drop for channel lineup, scheduling, ordering, editing. - Better defaults/templates for channel creation (subtitles, shuffle, schedule/playout defaults). - Advanced config discoverable without making common workflows heavy. - Rebrand user-facing surfaces to ChicoryTV. **Success for Pass 1:** the user (not design-oriented) can look at 4 rendered hero screens and say "yes, that direction" — locking a look + brand cheaply before any spec/prototype/build work. --- ## 2. Strategic decisions (locked 2026-07-01) | Decision | Choice | Why | |---|---|---| | **Frontend stack** | **React SPA on the REST API** (not Blazor/MudBlazor reskin) | All design is AI-driven; LLMs generate React far more reliably than Blazor. Claude Design outputs React, so its output is *shippable* and the `design-sync` pipeline becomes usable (on-brand AI designs → 1:1 shipped code). Satisfies #59's "around the API" goal natively. | | **API sequencing** | **Design pulls the API** | If a design goal needs a new API feature, build the API feature first. #59 is *not* hard-blocked on API completeness. | | **Look & feel** | **Komodo-slick** | Dynamic, app-like, no full-page reloads, dense/technical. Explicitly **not** Sonarr-style. | | **Brand** | **ChicoryTV — dark + chicory blue** | See §3. | **Accepted costs of React:** full UI rewrite, dual-language (C# backend + TS frontend), new build/deploy step, transition period running both UIs. **Pipeline note:** `/design-sync` does **not** apply yet — MudBlazor isn't a React library. It becomes usable once a React component library exists, at which point real ChicoryTV components can be synced into Claude Design. --- ## 3. Brand: ChicoryTV "Chicory" is a real plant with a distinctive cornflower/periwinkle-blue flower (and a coffee/roasted association) — giving an ownable accent color and a name with a story. Direction: **dark, technical, focused**, one confident accent. ### Color tokens (draft — refine in Claude Design) ``` bg #0F1115 (near-black charcoal — app background) surface #171A21 (cards / panels) border #262B36 (hairline dividers) text #E6E9EF (primary) muted #9AA4B2 (secondary) accent #5B7CFA (chicory periwinkle-blue — primary actions, active nav) ok #3FB984 warn #E0A83D err #E5484D ``` ### Usage rules - Accent used **sparingly** — primary buttons, active nav item, focus/selection, "live/on-air" emphasis. Not decorative. - Dense rows with subtle hairline borders; generous but not wasteful spacing. TV/EPG grids read well on dark. - **Typography:** clean sans (Inter-like) for UI; consider a tabular/mono for channel numbers, times, and durations so grids align. - **Density:** app-like, information-dense (Komodo), not marketing-spacious. Prefer inline actions and hover affordances over full-page navigation. - **Logo/wordmark:** "ChicoryTV" wordmark with a chicory-flower/periwinkle mark; let Claude Design propose 2-3 options. --- ## 4. The 4 hero screens (Pass 1) Real domain vocabulary is included so renders show true ChicoryTV content, not placeholders. **Use the app's own terms:** Channels, Schedules / Schedule Items, Playouts (Classic/Block/Sequential/Scripted/External JSON), Blocks, Playout Templates, Deco / Deco Group, Filler (Pre/Mid/Post-Roll, Tail, Fallback), Collection Type, Playback Order, Playout Mode, Guide Mode, and the XMLTV "programme" for EPG. ### 4.1 Dashboard (reimagined as a real overview) Today `Index.razor` is only health-checks + release notes. **Redesign it into a proper landing overview:** - **On-air now** — per-channel "now playing" strip/cards: channel number + logo + name, current program title, progress bar to next, live/on-air accent state. - **At-a-glance counts** — channels, active playouts, transcodes running, libraries. - **Health panel** — the existing `HealthCheckResult` list (status: Pass/Info/Warning/Fail with green/blue/amber/red), condensed; click-through to detail. - **Recent activity / errors** — recent scans, playout resets, transcode failures. - **Release notes** — collapsible card, secondary. ### 4.2 Channels list Entity: `Channel`. Dense table, the template for all list pages. - **Columns:** Number (with `(D)` disabled / `(H)` hidden-from-EPG markers) · Logo · Name · Language (preferred audio) · Streaming Mode (`HLS Direct` / `HLS Segmenter` / `MPEG-TS` / `MPEG-TS (Legacy)`) · FFmpeg Profile. - **Row actions (inline icons):** Preview · Stop transcode (only when active) · Edit · Troubleshoot playback · Delete. - **Top bar:** "Add Channel", "Edit Channel Numbers", "Show Disabled" toggle, search/filter. - **States:** disabled/hidden rows visually de-emphasized; active-transcode indicator. - **Redesign opportunity:** bulk-select + bulk actions; group-by channel Group; drag-to-reorder channel numbers (replaces the separate "Edit Channel Numbers" page). - **Borrowed-concept enrichments:** - **Lineup health at a glance** (#72) — per-row status: user-made vs auto-generated origin, and a prominent **"failed / no content"** state (empty collection, no playout, broken source). - **Resume badge** (#68) — sequential/resume channels show a "Continue watching — resumes at S1E4 12:30" indicator. ### 4.3 Schedule / playout editor (introduce drag-and-drop) **Net-new capability:** today, schedule-item ordering is up/down arrow buttons. The redesign introduces **drag-to-reorder**. - **Left:** ordered list of **Schedule Items** (drag handles) — each row shows Start Time · Collection · Playout Mode. - **Right:** selected-item detail form. Real fields: - **Start Type** (Dynamic/Fixed) + Start Time + Fixed Start Time Behavior (Inherit/Strict/Flexible) - **Collection Type** — Collection, Television Show/Season, Artist, Multi Collection, Smart Collection, Search Query, Playlist, Rerun (First Run / Rerun) — each swaps its picker. - **Playback Order** — Chronological, Random, Shuffle, Shuffle In Order, Marathon, Season/Episode, Multi-Episode Shuffle (+ Marathon sub-fields: Group By, Shuffle Groups/Items, Batch Size). - **Playout Mode** — Flood / One / Multiple / Duration (+ Multiple Mode & Count, Playout Duration). - **Fill With Group Mode, Tail Mode, Custom Title, Guide Mode (Normal/Filler)**. - **Filler** — Pre-Roll, Mid-Roll, Post-Roll, Tail, Fallback presets. - **Overrides** — Watermarks, Graphics, Preferred Audio/Subtitle Language, Subtitle Mode. - **Discoverability:** show the common fields (Collection, Playback Order, Playout Mode) up front; tuck Filler/Overrides into progressive-disclosure sections. - **Borrowed-concept enrichments:** - **Weighted / fair-share distribution** (#70) — per-show weight inputs (sliders or %) when a schedule item mixes multiple shows ("Show A 70% / Show B 30%"), plus a fair-share toggle. - **Persistent shuffle + Reroll** (#71) — a "Reroll" button and a visible shuffle-state indicator, so shuffle is deliberate and predictable rather than opaque. - **Pad to clock boundary** (#77) — an option to snap programs to :00/:15/:30 with filler, for tidy broadcast-style guides. - **Seasonal / date condition** (#73) — an optional date-range predicate on a schedule item ("active only between dates"). ### 4.4 Guide / EPG grid Today the guide is XMLTV output only (no rendered grid). Design a **dark time-grid** program guide. - **Layout:** channels down the left (number + logo + name), time across the top, program blocks in the grid. - **Program block** (`programme`): title, sub-title, start–stop times, category chip, artwork/icon, description on hover/expand. - **States:** "now" vertical time-marker; current/on-air program gets the accent; filler (Guide Mode = Filler) visually distinct from real programs. - **Controls:** time-range scrubber, jump-to-now, channel filter. --- ## 5. How to use this in Claude Design Open claude.ai/design and create a project (e.g. "ChicoryTV"). Paste the **master brief** first, then generate one screen at a time with the per-screen prompts. Iterate on the look on the Dashboard first (it sets the shell), then apply the locked style to the rest. ### Master brief (paste first) > Design **ChicoryTV**, a dark, slick, app-like admin UI for a self-hosted IPTV/custom-TV channel server (think a modern take on a media-server admin, in the spirit of Komodo — dense, technical, no full-page reloads). Dark theme: background `#0F1115`, surfaces `#171A21`, hairline borders `#262B36`, primary text `#E6E9EF`, muted `#9AA4B2`. One accent — chicory periwinkle-blue `#5B7CFA` — used only for primary actions, active nav, focus, and live/on-air states. Status colors: ok `#3FB984`, warn `#E0A83D`, error `#E5484D`. Clean sans UI type; tabular/mono for numbers, times, durations. Left sidebar nav (Dashboard, Channels, Schedules, Playouts, Collections, Libraries, Settings), compact top bar. Information-dense, inline actions, hover affordances. Include a "ChicoryTV" wordmark with a small periwinkle chicory-flower mark. ### Per-screen prompts 1. **Dashboard:** "A landing overview: an 'On air now' section of per-channel cards (channel number, logo, name, current program title, progress bar to next, live accent), a row of stat tiles (Channels, Active Playouts, Transcodes, Libraries), a condensed Health panel (rows with Pass/Info/Warning/Fail status icons in green/blue/amber/red), a Recent activity list, and a collapsible Release notes card." 2. **Channels list:** "A dense channels table. Columns: Number, Logo, Name, Language, Streaming Mode (values like 'HLS Segmenter', 'MPEG-TS'), FFmpeg Profile. Inline row actions: preview, edit, delete. Top bar: 'Add Channel', 'Show Disabled' toggle, search. Disabled rows de-emphasized. Bulk-select checkboxes. Each row has a small status dot — green for healthy, red for 'no content / won't play', and a subtle 'auto' tag for auto-generated channels; a couple of rows show a 'Continue watching — resumes at S1E4' badge." 3. **Schedule editor:** "Two-pane schedule editor. Left: a drag-to-reorder list of schedule items (drag handles), each showing start time, collection name, and playout mode. Right: a detail form for the selected item with Collection Type, Playback Order, and Playout Mode as the primary fields, and collapsible 'Filler' and 'Overrides' sections. Show a 'Reroll' button next to a shuffle indicator; when the item mixes multiple shows, show per-show weight sliders; include a 'Pad to :00/:30' toggle and an optional date-range 'active between' condition. Dark, dense." 4. **EPG grid:** "A dark TV program guide grid: channels down the left (number, logo, name), time across the top, program blocks in the grid with title/sub-title and a category chip. A vertical 'now' time marker; the current program on each channel uses the accent color; filler programs look muted. A jump-to-now button and time scrubber." 5. **Auto-tuning wizard** *(borrowed from PseudoTV, #69)*: "A 'Generate channels' screen. Step 1: choose what to generate channels from — a set of toggle cards labelled 'By TV Network', 'By TV Genre', 'By Movie Genre', 'By Studio', 'One per Show (24/7)', 'By Smart Collection'. Step 2: a preview grid of the channels that would be created — each a card with an auto-picked logo, a channel name (e.g. 'Comedy', 'Warner Bros.', 'Breaking Bad 24/7'), an item count, and an include checkbox. A 'Template' dropdown applies default settings to all. A prominent 'Create 12 channels' button. Dense, app-like." Refine tokens/typography live, then regenerate the other screens once the Dashboard look is locked. > **Enrichments cross-reference:** the annotations above map to filed issues — Channels-list status/resume (#72, #68); Schedule-editor weights/reroll/pad/seasonal (#70, #71, #77, #73); Auto-tuning (#69). These enrich the hero screens; they're not separate deliverables except the Auto-tuning wizard (screen 5). --- ## 6. Create Channel — workflow redesign (pulled forward) The inherited channel-creation flow is the biggest UX pain and is being fully rethought. Today, making a working channel is a chain of four disconnected editors across four entities — **Channel → Schedule → Schedule Items → Playout** — and the channel form alone dumps ~30 advanced fields with no sane defaults. There is no way to browse your library while building, and no templates/presets. ### Target experience: one library-to-lineup builder **One screen** replaces the four-editor chain. Behind the scenes it still creates Channel + Collection + Schedule + Schedule Items + Playout — the user never sees those concepts. - **Left — Library browser:** artwork grid of shows/movies, searchable, filterable by library. (Wholly missing today.) - **Right — Channel lineup:** items added from the library, drag-to-reorder. This *is* the channel's content. - **Add by** double-click **or** drag. **Friendly options, always visible (the 90% case):** - **Name** + auto-suggested channel **Number**. - **Shuffle** toggle (on = Shuffle playback order; off = Sequential/Chronological). - **"Always playing (like live TV)"** toggle — plays continuously and advances on schedule even when unwatched. *(Needs backend confirmation — see gap 6.)* - **Channel image:** drop one image, used by default as **both** the listing **logo** and the on-screen **bug** (watermark), with live preview of both; expandable to set them separately (as possible today). **Technical settings = a Channel Template (with override):** - A **Channel Template** picker bundles the clunky technical/behavioral config — FFmpeg/transcode profile, fillers (pre/mid/post-roll), interleaving, subtitle behavior, playout defaults. A sensible default template is pre-selected, so most channels need **zero** technical config. - **Both built-in and custom templates:** ship a few sensible built-ins (e.g. "Standard", "Music videos"); users can save their own. Where a template can supply a default, it does — templates are the assumed path. - **"Advanced"** disclosure reveals the full ~30-field set for power-user overrides. **One "Create" button** builds all underlying entities atomically. ### Backend gaps this requires (design pulls the API) Tracked under epic **#62**; sub-issues #63–#68: 1. **Composite "create channel from lineup" endpoint** (#63) — creates channel + collection + schedule + schedule items + playout atomically (today they are separate operations). 2. **Channel Templates entity** (#64) — bundles transcode profile, fillers, interleave, subtitle/shuffle/playout defaults; built-in + user-saved. (#59 explicitly asks for templates.) 3. **Library browse + search API with artwork** (#65) — powers the left pane. 4. **Full image-type support for logo/watermark** (#66) — WebP appears unsupported today. Support can mean *either* adding decode support *or* **transparently re-encoding uploaded images to a supported format on upload** if FFmpeg/SkiaSharp is the blocker — the user should never hit an "unsupported image" wall. 5. **Unified logo/bug image handling** (#67) — one uploaded image drives both, separable. 6. **"Always-on vs on-demand" playout** (#68) — needs investigation; ErsatzTV playouts are continuous by design, so an on-demand mode may not exist yet. ### Claude Design prompt — Create Channel > A "Create Channel" screen for a dark IPTV admin (ChicoryTV palette). Two main panes: LEFT is a searchable library browser — a grid of show/movie poster artwork with a search bar and a library filter dropdown. RIGHT is the "channel lineup" — a vertical list of the shows added from the library, each with a drag handle to reorder and a remove button. Above the panes: a channel Name field, an auto-filled channel Number, a Shuffle toggle, an "Always playing (like live TV)" toggle, and a single image drop-zone labelled "Channel image" showing a live preview used as both the listing logo and the on-screen bug, with an "advanced: set separately" link. A "Template" dropdown (default: "Standard") sets technical settings, with an "Advanced settings" collapsible section below it. A prominent "Create channel" button. Dense, app-like, chicory periwinkle-blue accent on the primary button and active elements. --- ## 7. Out of scope & next steps **Out of scope now:** the full #59 implementation spec, React app architecture (routing/state/auth/build/deploy), the media-libraries/collections browser (Pass 2), browser-based channel playback (tracked separately in #60), the actual rebuild. (Channel creation was originally deferred to Pass 2 but is now specified in §6.) **Next steps (after a look is locked):** 1. Design the §6 Create Channel screen in Claude Design; file the §6 backend-gap issues. 2. Pass 2 screens: libraries/collections browser. 3. Prototype the hard workflows (drag-drop lineup/scheduling, create-channel builder) as clickable React. 4. Full #59 spec: IA, React app architecture, API gaps to backfill, migration/cutover (dual-stack), rebrand checklist. 5. Build. **Related:** #2 (REST API — the foundation this UI sits on), #58 (MCP server), #60 (browser channel playback, post-redesign).