phase: 171_admin_settings_layout
Build and Push Containers / build-and-push-app (push) Successful in 1m34s
Build and Push Containers / build-and-push-db (push) Successful in 14s

Expected state: only `00_phase.md` remains in `todo/` (the harness moves it on success; I must not touch it). All verification is complete.

---

**Phase 171 final verification pass — report**

- **Verified (all 4 tasks complete, CSS-only diff confirmed byte-exact to contract):** `#settings-content` flex column + `gap: 1.25rem` (tasks 01); `.settings-group-row th` band `--brand-soft` + 700 + `--line` top hairline (02); `#settings-save:disabled` `cursor: default` (03); new phase-dedicated Playwright suite (04). Mobile media queries and `settings.js`/`app/` byte-untouched, as pinned.
- **Gates:** `uv run pytest --cov=app --cov-report=term-missing` → **4069 passed, app/ 99%** (>90%); `uv run ruff check .` → clean; `uv run pyright` → **0 errors, 0 warnings**.
- **E2E (in isolation):** `test_admin_settings_layout.py` → **5 passed**; `test_admin_settings_panel.py` (phase 168) → **12 passed**; `test_wide_desktop_column.py` → **3 passed**.
- **Completion criteria:** search/table no-intersection + gapped action row at 1440/375 px ✅ · distinct group bands (bg ≠ card, weight 700, ≥1px top hairline) ✅ · disabled Save `cursor: default` with §7.4 dim + aria-busy lifecycle intact ✅ · full suite + coverage + lint ✅ · all three E2E suites isolated ✅ · atomic commit + dir move = **harness's job** (task files already in `complete/`; per protocol I left every change uncommitted in the working tree).
- **Documentation:** README.md (all 1487 lines) and AGENTS.md (all 80 lines) fully reviewed — every config default cross-checked vs `app/config.py`, all quick-reference commands verified against existing files, AGENTS.md rules/contracts verified vs code — **verified consistent, no changes needed** (phase 171 is CSS-only: no setup/command/env/API impact).
- **Notable:** one phase-168 test failed on the first isolated run solely because an unrelated `undercooked` dev server held port 8124 (the suite's `DISABLED_PORT`); re-ran with the suite's built-in `E2E_APP_PORT=8300` override — no code change, foreign process untouched. Post-run DB state clean (`app_settings` 0, `ui_settings` 0, e2e tokens 0).
- **Next pending phase:** none — phase 171 was the last `todo/` phase.
This commit is contained in:
2026-10-10 04:45:34 -04:00
parent c4f098d0c0
commit e9ae6e2ba3
28 changed files with 1520 additions and 4 deletions
+37 -4
View File
@@ -4674,6 +4674,23 @@ a.answer-image:hover { text-decoration: underline; } /* flat — the caption und
gap: 1.25rem;
flex: 1;
}
/* Phase 171 (task 01; TODO L4): the #settings-content block —
the disabled banner, the status + error lines, the search row,
the .table-wrap card, and the Save / Clear-all action row —
stacks with ONE uniform gap: the shell's own 1.25rem
(ASSUMPTION A4: no new spacing value; the 640px mobile
stacking composes with it unchanged). The gap kills both
layout complaints at once: the search box clears the table
card (the "overlap") and the action row separates from the
table (the "smushed"). NO per-element margins: the gap is the
ONLY spacing source; the #settings-status / .settings-error
min-heights already reserve their lines (the gap is additive
and uniform). */
#settings-content {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
/* The catalogue: FULL-WIDTH (AGENTS.md rule 5 — the .git-sources-
table language: no skinny list), one cell per column, the
.table-wrap card + its bounded scroll + the sticky thead carry
@@ -4691,13 +4708,27 @@ a.answer-image:hover { text-decoration: underline; } /* flat — the caption und
border-bottom: 1px solid var(--line);
}
.settings-table td { white-space: nowrap; }
/* The group band: the --surface row, ink text (15.3:1, AA). */
/* Phase 171 (task 02; TODO L4, owner-locked A3): the group band.
Today's defect: background --surface — the SAME fill as the
.table-wrap card, so the band is invisible. The fix: the
--brand-soft tint (the SOLID hex the sticky thead rule
documents at .table-wrap — rows never show through, and a
themed page's #bor-theme override of the token handles the
color — B4; no new palette variable, B3), weight 700, and a
--line top hairline so a band is delimited above AND below
(the border-bottom comes from the .settings-table th family)
and can never merge with the card's top edge or the band
above it. The text stays --ink on --brand-soft — 14.8:1 (AA;
the :root documented pairing). Static, text-only, no animation
(nothing for prefers-reduced-motion to still). */
.settings-group-row th {
background: var(--surface);
background: var(--brand-soft);
color: var(--ink);
font-weight: 700;
font-size: 0.82rem;
text-transform: uppercase;
letter-spacing: 0.04em;
border-top: 1px solid var(--line);
}
.settings-table tbody tr.settings-row:hover td { background: var(--bg); }
/* The Setting cell: the label (bold) over the BOR_* name (mono,
@@ -4808,7 +4839,9 @@ a.answer-image:hover { text-decoration: underline; } /* flat — the caption und
}
#settings-filter:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
/* The action row: Save (the .token-generate brand pill — the
§7.4 in-flight state is the dimmed :disabled + aria-busy) and
§7.4 in-flight state is the dimmed :disabled + aria-busy; the
disabled cursor is `default` — the .settings-reset:disabled
idiom — the wait cursor was never part of §7.4) and
Clear all (the .token-revoke ghost — the destructive err hover
pair; the two-step confirm reuses the .history-confirm-* rules
unchanged). */
@@ -4832,7 +4865,7 @@ a.answer-image:hover { text-decoration: underline; } /* flat — the caption und
cursor: pointer;
}
#settings-save:hover:not(:disabled) { background: var(--brand-hover); color: var(--bg); }
#settings-save:disabled { opacity: 0.6; cursor: wait; }
#settings-save:disabled { opacity: 0.6; cursor: default; }
#settings-clear-all {
min-height: 44px;
padding: 0.35rem 0.7rem;