Wizard polish: step headlines, gated Next, real summary, portal action bar

Mobile only (<=639px); desktop markup untouched.

Bug fix: the Back/Next bar was fixed-positioned inside the screen
entrance animation's transformed wrapper, so it painted under the content
and jumped to the viewport bottom about a second in. It is now portalled
to <body> and only fades in, pinned to the bottom from the first frame.
The other fixed/sticky elements (tab bar, drawer, sheets, install sheet)
were checked and live outside the animated wrappers.

- The step name is now the large headline with a one-line description;
  the repeated page title is dropped on phones. Thin progress bar + 1/3.
- Step 1: formats/limits hint, one big dashed Add photos or files area
  (plus icon), Camera and Paste text instead as secondaries, and a
  'nothing added yet' placeholder that becomes the thumbnail/chip list.
- Next is disabled until a photo, file or pasted text exists; step 3 can
  never be reached empty.
- Step 1 shows Cancel (back to the Library) instead of a dead Back.
- Step 3 is a real summary: thumbnail/chip strip plus Files, Difficulty,
  Activities and Folder rows, each with an Edit link to its step; Freeze
  is the single primary action.
- Step 2 got a visible Difficulty label and a helper line under every
  group, defaults still preselected.
- Bottom chrome: flat full-width Back/Next bar above the safe area, and
  the tab bar hides inside both wizards. The lower-right orb is hidden on
  phones so it can never glow behind the bar.
- Make my homework matches: headline, hint, big add area, placeholder,
  Cancel, gated Next, flat bar.

Verified: new wizard suite 80/80 (bar position sampled at 5 frames during
the entrance from tab bar/drawer/empty state; 360 + 390, dark + light,
EN + CS, reduced motion on/off; gating, summary Edit links, hidden tab
bar and orb), declutter 116/116, regression 74/74, mobile 52/52,
animation 8/8, i18n 25/25. Lint + build clean. SW freezmo-v22.
This commit is contained in:
Martin Dvořák 2026-10-10 11:35:45 +00:00
commit e66141e9a0
9 changed files with 338 additions and 132 deletions

View file

@ -43,12 +43,16 @@ no database, no data leaving your machine except the requests you send to Ollama
**Capture & generate**
- Drag & drop, file picker, **mobile camera capture** and **clipboard paste** (Ctrl/⌘+V)
- **Phones get a 3-step flow** — notes → options → summary — with a progress bar and a
floating Back / Next bar above the tab bar. Step 1 is just *Add photos or files*,
*Camera* and a *Paste text instead* field (no drop zone on touch screens); step 2 keeps
folder, difficulty and activity count at their defaults and tucks the topic hint and
pasted notes behind one collapsed row; step 3 is a single summary line with **Freeze my
deck**. Going Back keeps every input. The desktop page is unchanged.
- **Phones get a 3-step flow** — notes → options → summary — with a thin progress bar and
“1 / 3”. Step 1 leads with the step name as the headline, a formats/limits hint, one big
*Add photos or files* area plus *Camera* and *Paste text instead*, and a “nothing added
yet” placeholder that becomes the thumbnail/chip list. Next stays disabled until something
is added. Step 2 keeps folder, difficulty and count at their defaults with a helper under
each group and tucks the topic hint and pasted notes behind one collapsed row. Step 3 is a
real summary — thumbnails/chips, files, difficulty, activities and folder, each with an
*Edit* link back to its step. A flat Back/Cancel + Next/Freeze bar sits at the bottom above
the safe area (the tab bar hides inside the wizard), and it is portalled to `<body>` so the
screen entrance animation can never displace it. The desktop page is unchanged.
- **Photos and documents**: JPG/PNG/WEBP/HEIC images plus **PDF, DOCX, PPTX, ODT/ODP/ODS, TXT, MD, CSV**
- Documents are read **in the browser**: PDF text layers are extracted, scanned PDF pages are rendered
as images for the vision model, DOCX/PPTX text, speaker notes and embedded images are pulled out.
@ -92,8 +96,10 @@ no database, no data leaving your machine except the requests you send to Ollama
- Two modes: **Just make it** returns the finished homework (the answer only, ready to copy), and
**Explain how to make this homework** turns it into a guided walkthrough
- On phones this is a **2-step flow**: the assignment first (same simplified input as the
deck flow), then the two mode cards under a short preview — tapping a card starts it
immediately, so there is no separate button. Desktop keeps the select-then-confirm layout.
deck flow, with its own step headline, formats hint, big add area and empty placeholder),
then the two mode cards under a short preview — tapping a card starts it immediately, so
there is no separate button. Step 1 starts with *Cancel* and the flat action bar matches
the deck wizard. Desktop keeps the select-then-confirm layout.
- The guide is one step per screen in the same snap-feed feel as the study feed: what to do and
why, **three progressive hints** per step (nudge → hint → the full answer), and a **checkpoint**
built from the normal activity components and graded through `/api/grade`
@ -954,6 +960,16 @@ Things I chose while building, with the reasoning:
the same feature set the current `motion` import already pulls in. Verified with a
4x-CPU-throttled mobile trace (no long tasks, CLS 0) and a reduced-motion run.
38. **Wizard chrome lives outside the animated tree.** The step name is the headline, the
action bar is a flat full-width bar at the bottom (the tab bar hides inside the wizard),
and the bar is rendered through a React portal to `<body>`. That last part is a real bug
fix: the screen entrance animation puts a transform on the content wrapper, and a
transform on an ancestor becomes the containing block for `position: fixed`, so the bar
used to paint inside the content and jump to the viewport bottom a second later. It now
only fades in, pinned to the bottom from its first frame — verified by sampling its
position across the entrance (5 frames, 60–450ms) from the tab bar, the drawer and the
empty state, at 360/390, both themes, both languages and with reduced motion.
14. **`gpt-oss:120b` does all content work — but it cannot read images** (`this model does not
support image input`), so `VISION_MODEL` has to stay a multimodal model (`gemma4:31b-cloud`).
Text-only inputs — pasted text, PDFs with a text layer, DOCX/PPTX/ODT — never touch the vision