phase: 149_sync_progress_box
All verification complete. The `ink-soft`/`--surface` pair the box uses is already pinned AA by the existing theme E2E suites (8.2:1 dark, ~6.9:1 light). Everything is green — no fixes were needed.
**Phase 149 final verification report**
- Verified (no re-work needed): `#sync-progress` box wiring (single `setSyncLabel` writer with `running` flag; `is-running` class travels with the spin; aria-label owned by the writer), the panel/icon-only-button CSS, and the 5-test dedicated E2E; all 6 pre-existing sync E2Es' running pins migrated to the box, settled pins untouched.
- Dedicated E2E: `uv run pytest tests/e2e/test_sync_progress_box.py -v --no-cov` → **5 passed in 198.6 s** (isolation, slow-proxy mock; under the 600 s budget).
- Full suite: `uv run pytest --cov=app --cov-report=term-missing` → **3463 passed, app/ coverage 99%** (>90% gate).
- Migrated sync E2Es, each in isolation: `test_sync_button` 3 passed, `test_sync_cancel` 3, `test_sync_chunk_progress` 2, `test_sync_label_mobile` 4, `test_sync_summary_visibility` 3, `test_sync_upload_progress` 4 — all green.
- Lint/types: `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors.
- Criteria: in-flight spinner-only button + full untruncated wrapped box (desktop & mobile 390×844, `scrollWidth ≤ clientWidth`) ✓; settle byte-identical ("Synced HH:MM" + `3 added`, box hidden, aria restored) ✓; `#sync-result` sole live region (box `aria-hidden`), mid-run reload re-attaches ✓; WCAG (AA contrast both themes via the pinned ink-soft/surface pair, focus-visible, reduced-motion kill intact at styles.css L2201) ✓; cancel/409/error/upload/status API unchanged (green suites above) ✓.
- Documentation: README.md reviewed in full (sync-states paragraph now matches the shipped UI; env-var table matches `app/config.py` and covers all `.env.example` vars; pages/commands verified) and AGENTS.md reviewed in full — **verified consistent, no changes needed**.
- Notable: no defects found in this or prior work; no live infrastructure touched.
- Next pending phase: none — `todo/` will be empty once the harness moves 149 (only 149 was pending).
This commit is contained in:
@@ -2236,6 +2236,50 @@ a.answer-image:hover { text-decoration: underline; } /* flat — the caption und
|
||||
white-space: nowrap;
|
||||
font-family: var(--mono); /* the same pinned-part language as the count (position reads as data) */
|
||||
}
|
||||
/* Phase 149 (task 02): the sync detail box — the house's bordered panel
|
||||
language (the .page-head card: --surface fill, 1px --line border,
|
||||
the house radius; --line is decorative, no contrast duty, like every
|
||||
other house border). It sits in the .sources-shell flex column whose
|
||||
1.25rem gap IS the house spacing above and below — no margin-top
|
||||
(it would double the gap). min-height ≈ 2 lines (0.8rem mono at the
|
||||
body 1.55 line-height, + the 0.75rem block padding + the 2px border,
|
||||
border-box) so even a one-line label reads as a calm panel with
|
||||
breathing room. The box is hidden-attr-driven (the global [hidden]
|
||||
!important rule keeps it display:none at idle — it exists only while
|
||||
a run is in flight). Mobile: a block in the same .container rides the
|
||||
100%-width phone shell — full width with no override (task 03's E2E
|
||||
asserts it at 360px). */
|
||||
.sync-progress {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius);
|
||||
padding: 0.75rem 1rem;
|
||||
min-height: 4rem;
|
||||
}
|
||||
.sync-progress-text {
|
||||
display: block;
|
||||
font-family: var(--mono); /* the .sync-result mono language (position reads as data) */
|
||||
font-size: 0.8rem; /* the .sync-result size */
|
||||
line-height: 1.55; /* the house body line-height */
|
||||
color: var(--ink-soft); /* the .sync-result ink — a PINNED identity pair on --surface
|
||||
(8.2:1 on the built-in dark, AA in both built-ins; the
|
||||
theme gate keeps any custom theme at >= 4.5:1) */
|
||||
overflow-wrap: anywhere; /* THE POINT of the box — a long source/relative/path WRAPS
|
||||
inside the panel; the pre-phase pill ellipsis is retired
|
||||
for the live detail (never clipped) */
|
||||
}
|
||||
/* Phase 149 (task 02): the running button IS the loading spinner (the
|
||||
owner's ask) — the label parts hide via the .is-running class
|
||||
(sources.js adds/removes it exactly where the icon's .is-spinning
|
||||
travels). The pill's padding/border stay, so the control never
|
||||
collapses: the 16px icon centers in a ~47x44px pill (desktop) or the
|
||||
full-width 44px bar (mobile — the pre-phase .sync-btn { width: 100% }
|
||||
rule keeps the big in-flight target, viewport-agnostic rule defined
|
||||
ONCE here). :hover, :disabled, and :focus-visible are untouched —
|
||||
they live on the .sync-btn element, and hiding the label span touches
|
||||
neither. The idle "Sync sources" label (and the mobile ellipsis rules
|
||||
for it) render exactly as pre-phase when the class is absent. */
|
||||
.sync-btn.is-running .sync-label { display: none; }
|
||||
/* Last-result announcer — soft ink, small mono */
|
||||
.sync-result {
|
||||
display: block;
|
||||
|
||||
Reference in New Issue
Block a user