techfreakworm commited on
Commit
fc74e8b
Β·
unverified Β·
1 Parent(s): 33862a6

docs: spec for Topaz Cinema Slate palette + drawer layout

Browse files
docs/superpowers/specs/2026-05-01-topaz-drawer-redesign-design.md ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Visual redesign β€” Topaz Cinema Slate + Drawer layout
2
+
3
+ **Date:** 2026-05-01
4
+ **Status:** Draft, awaiting user review
5
+ **Related:** `2026-04-30-ltx23-aio-generator-design.md` (original spec)
6
+
7
+ ---
8
+
9
+ ## Goal
10
+
11
+ Replace the current `gr.themes.Soft()` cream + purple palette with a dark slate-and-amber palette (**Topaz Cinema Slate**), and replace the always-visible left sidebar with a **hamburger drawer** that opens by default on desktop and is hidden by default on tablet/phone. Both changes are surface-level β€” no logic or backend changes.
12
+
13
+ ## Why
14
+
15
+ The current palette reads as a hobby AI demo, not a creative-pro tool. Slate-on-slate is gentlest on the eye when judging color-graded video output, and an amber CTA reads "render," not "alert." The drawer pattern gives the form panel full screen real estate on phones (the sidebar currently stacks above the form on `<700px`, eating half the viewport for nav), while still keeping the sidebar always-visible at desktop widths where it costs nothing.
16
+
17
+ ## Theme tokens
18
+
19
+ Applied via `gr.themes.Base().set(...)` overrides on the Blocks theme:
20
+
21
+ | Token | Value | Used for |
22
+ |---|---|---|
23
+ | `body_background_fill` | `#12161B` | App background |
24
+ | `background_fill_primary` | `#12161B` | Form/page background |
25
+ | `background_fill_secondary` | `#1A1F26` | Card / panel surface |
26
+ | `block_background_fill` | `#1A1F26` | Component (input, slider) surface |
27
+ | `body_text_color` | `#E6E8EB` | Primary text |
28
+ | `body_text_color_subdued` | `#7C8693` | Secondary / hint text |
29
+ | `border_color_primary` | `#262C35` | Card / input border |
30
+ | `border_color_accent` | `#E0A458` | Focused input ring |
31
+ | `button_primary_background_fill` | `#E0A458` | Generate button |
32
+ | `button_primary_text_color` | `#12161B` | Generate button label |
33
+ | `error_background_fill` | `#3A1E20` | Error banner background |
34
+ | `error_text_color` | `#F4A6A8` | Error banner text |
35
+
36
+ Fonts: `IBM Plex Sans` (UI 14 px) + `IBM Plex Mono` (mono 13 px), loaded from Google Fonts in the page `<head>` (Gradio's `head` parameter on `Blocks`, or via `_CUSTOM_CSS` `@import`).
37
+
38
+ ## Layout: hamburger drawer
39
+
40
+ ### Markup structure (logical, Gradio components)
41
+
42
+ ```
43
+ gr.Row() # header
44
+ β”œβ”€β”€ HamburgerButton (gr.Button, ≑ icon) # toggles drawer
45
+ β”œβ”€β”€ gr.Markdown("LTX 2.3 Studio") # title
46
+ └── ActiveModeTag (gr.Markdown, amber pill) # shows current mode
47
+
48
+ gr.Row(elem_classes="layer")
49
+ β”œβ”€β”€ gr.Column(elem_classes="drawer", visible=...) # 220 px wide
50
+ β”‚ └── 6 mode buttons (existing)
51
+ └── gr.Column(elem_classes="body-pane")
52
+ └── gr.Tabs(elem_classes="hidden-tabs") # current 6 mode tabs
53
+ ```
54
+
55
+ ### Open / closed behavior
56
+
57
+ - **Desktop (β‰₯1024 px):** drawer open by default, occupies the left 220 px of the viewport. Hamburger still works as a toggle but most users leave it open.
58
+ - **Tablet (700–1023 px):** drawer closed by default; opening it slides over content with a translucent overlay (`background: rgba(0,0,0,0.5)`). Tapping outside closes.
59
+ - **Phone (<700 px):** same as tablet, but drawer takes 80 % of viewport width when open.
60
+
61
+ State persists in `localStorage` (`ltx-drawer-open` key) so a user who closes the drawer on desktop stays closed across reloads.
62
+
63
+ ### Active mode header tag
64
+
65
+ A small amber-bordered pill in the header (e.g., `T2V`, `A2V`, `LIPSYNC`) showing the currently selected mode. Updates whenever a mode button is clicked. Uses `IBM Plex Mono` 11 px so it reads as a label, not a button.
66
+
67
+ ### CSS approach
68
+
69
+ Pure CSS, no JS framework. Use `:has()` and `<input type="checkbox">` hidden control for drawer toggle, OR a tiny inline `<script>` block that toggles a class on the body. Gradio doesn't sandbox custom scripts in `_CUSTOM_CSS`, but it does support the `head` parameter on `gr.Blocks` for inline `<script>`.
70
+
71
+ Existing media queries (`@max-width: 700px`, `@max-width: 1024px`) collapse to a single `@max-width: 1023px` block since drawer behavior only differs at the desktop boundary.
72
+
73
+ ## Files touched
74
+
75
+ - `app.py` β€” Blocks `theme=`, `head=` (fonts + drawer toggle script), `_CUSTOM_CSS` rewrite, header markup, drawer column wrapping the existing mode buttons
76
+ - `README.md` β€” update screenshot if any (defer; we don't have one yet)
77
+
78
+ No changes to `backend.py`, `models.py`, `modes.py`, `workflow.py`, `ui.py`.
79
+
80
+ ## Out of scope (do not touch)
81
+
82
+ - Form layout inside each mode tab (prompt input, parameter sliders) β€” typography updates only via theme token cascade
83
+ - Model status / settings panel content β€” these display the same info, just on the new palette
84
+ - Mode set, generate flow, progress events β€” backend unchanged
85
+ - Any CUDA / MPS / Spaces logic
86
+ - Custom LoRA UI (still v1.1+)
87
+
88
+ ## Testing plan
89
+
90
+ 1. `python app.py` locally on macOS, browse `http://127.0.0.1:7860`
91
+ 2. Resize Chrome window: full width β†’ 1024 px β†’ 700 px β†’ 380 px. Drawer should:
92
+ - stay open β‰₯1024 px
93
+ - hide & become overlay-on-hamburger <1024 px
94
+ 3. Click each of 6 mode buttons; confirm:
95
+ - active mode tag in header updates
96
+ - drawer auto-closes on phone after click (open-on-tap β†’ click-to-pick β†’ close)
97
+ 4. Click Generate on T2V (with Balanced preset, 320Γ—480, 5 s). Confirm progress + output render correctly on the new palette.
98
+ 5. Trigger an error (e.g., empty prompt) and confirm error banner uses `#3A1E20` / `#F4A6A8`.
99
+
100
+ ## Risks
101
+
102
+ - Gradio's `head` parameter is on `gr.Blocks` since 4.x β€” confirm it accepts a multi-line string with `<script>`.
103
+ - `gr.themes.Base().set(...)` may not cover every component (e.g., `gr.Slider`'s track). If we hit a gap we add an `elem_classes` override and target it in `_CUSTOM_CSS` β€” incremental, low-risk.
104
+ - The hidden-checkbox-and-`:has()` toggle pattern has Safari β‰₯15.4 compatibility, fine for our audience.