Skip to content

Merchant portal design brief โ€‹

  • What this is: evidence for the overhaul, not a proposal for one. Every page measured at 1440x950 with its screenshot beside it. No layouts are suggested here, because the shape is hers to name.
  • Her verdict, 2026-08-28: "I still think the design overall needs to be considerably overhauled for all pages except for the offer creation/builder."
  • Scope: the seven merchant routes. The offer creation and builder flow is explicitly OUT, at her direction.
  • What is NOT in here: the defects. Those are fixed or filed in merchant-defect-survey-0828.md and are a separate matter from the design.
  • Three directions now answer this brief: directions/index.html puts them side by side, and each is a self-contained file in directions/ that opens straight from disk. They still propose no pick. This brief stays the evidence; the directions are what was drawn from it.

How was this measured? โ€‹

  • One signed-in pass over all seven routes at 1440x950, on a stack running the current branch. Harness: harness/page-density-0828.mjs, raw numbers in harness/page-density-0828.json.
  • Content area is .admin-main, 1130x950 on every route.
  • Fill is the share of that area occupied by a top-level content block. Nested blocks are not double counted.
  • Dead below is the empty window under the last block, in pixels, out of a 950px viewport.
  • Screenshots are screens/merch-0828-<route>.png, full page.

What do the seven pages actually look like? โ€‹

PageFillBlocksWidest blockDead below the last blockControlsBody text
Overview84.4%31034pxnone, it overflows by 82px4876 chars
Offers42.3%21034px339px11537
Venues22.1%11034px629px3107
Notes13.2%11034px721px124
Photos11.8%11034px736px0141
Account12.1%1520px552px6140
Settings7.8%1720px685px5160

What reads as wrong? โ€‹

D1. The container is a constant while the content varies by a factor of twenty. โ€‹

  • Five of seven pages stretch a 1034px block, 91.5% of the content area, around whatever they have. Notes puts 24 characters in that box. Offers puts 511.
  • The two exceptions make it worse, not better. Account sizes its card to 520px and Settings to 720px, which is the design skill's rule 4 (size content to its content) being followed on two pages and ignored on five. The portal is inconsistent with itself, so neither reads as a decision.
  • Screenshot to look at: merch-0828-notes.png. A full-width card holding the words "No notes."

D2. Five pages leave more than half the window empty below the last thing on them. โ€‹

  • 552px to 736px of nothing, out of 950. On Settings the reader sees a 117px card and then 685px of dark.
  • This is not the sidebar gap, which is a separate and now-decided matter. This is the main content area.
  • Overview is the only page that fills its window, and it overflows by 82px, so the range across the portal runs from overflowing to 92% empty with nothing in between.

D3. Every page wears the same header whether it introduces a dashboard or one sentence. โ€‹

  • The uppercase PageHeader plus subtitle renders identically on Overview (three blocks, 876 characters) and on Photos (one block, zero controls).
  • The header is the heaviest element on four of the seven pages.

D4. Three pages announce their own title twice. โ€‹

  • Venues: VENUES in the header, then Venues (1) as the card's heading. Notes: NOTES, then Internal Notes. Photos: PHOTOS, then Photos.
  • On a page with one card, the card's job is not to repeat the page.

D5. Two pages are mostly navigation to things that do not exist. โ€‹

  • Settings carries three tabs and two of them are marked SOON. Its one real tab holds a single 117px control card, so the page is 7.8% full and two thirds of its navigation is unavailable.
  • Account carries six tabs and three are SOON.
  • A tab strip advertising more absence than presence sets an expectation the page then fails.

D6. Two pages have almost nothing to do on them. โ€‹

  • Photos has ZERO interactive controls: it is a coming-soon paragraph on a full application shell.
  • Notes has one, an Edit button, above a card reading "No notes."
  • Whether these are pages at all is a structural question rather than a styling one.

D7. The Overview is the only page with data, and its own spacing was already called out. โ€‹

  • Her words on it, recorded in the survey as HERS 3: "simply even just the spacing here is fucked". Measured then: all four metric cards render exactly 208px tall because the grid stretches them, while the gap under the last sub-metric row is 1px on one card and 30px on two others.
  • Her words as HERS 4: "we honestly need to add more data to this".
  • Both are still open. Neither was in scope for the defect work, and the parity dashboard build is deliberately blocked on her reviewing the admin Dashboard shape.

What is the named gap? โ€‹

A rejected offer has no home anywhere in the merchant portal, and the reason it was rejected is already on the wire and read by nothing. โ€‹

  • Recorded here rather than patched, on a decision made 2026-08-28. The tempting fix was a Rejected row on the Overview's Active Offers card, and that fixes a visibility gap by breaking the card's meaning: a rejected offer is not active. The gap is bigger than the card.

What a merchant can see today. โ€‹

SurfaceWhat it does with a rejected offer
Offers list filtersAll, Active, Draft, Expired. There is no Rejected filter, so it is reachable only under All
Its badgeThe status map has no rejected entry, so it falls through to muted and looks identical to a draft
Overview's Active Offers cardBreaks out Draft and Expired. Rejected is absent
AnywhereNo reason, no next step, no way to know it will never run

The reason exists and nobody reads it. โ€‹

  • services/api/merchants/src/lib/serializeOffer.js serializes a moderation result, described in its own header as "why an offer was auto-rejected", and the merchant offer screens never reference offer.moderation.
  • So this is not a data gap. The answer is already arriving in the payload and no surface asks for it.

What it would take. โ€‹

  • A decision on where a rejected offer lives: its own filter beside Active and Draft, a callout on the landing surface, a banner on the offer itself, or some combination.
  • A distinct badge, so it stops reading as a draft. That is a one-line change once the placement is decided, and it is deliberately not made yet.
  • Surfacing the moderation reason, which is the part that turns "this did not run" into something a merchant can act on.
  • A view on whether a rejected offer can be edited and resubmitted, which is a product question rather than a design one and probably gates the rest.

What is NOT wrong? โ€‹

The offer creation and builder flow, which she named as the exception. โ€‹

  • Five numbered sections in a vertical rail, a live phone preview, a real select wrapper rather than a native one, and a form that fills its space.
  • Recorded here so the overhaul does not sweep it up. Two parts of it are locked artifacts under the design skill and must not be restructured: the phone preview and the vertical section sidebar.
  • Screenshot: merch-0828-offer-form.png.

The rail itself, as of today. โ€‹

  • The footer is pinned and the empty space above it is a decision she has now made. See footer-pin-988.md.

What would a decision need to answer? โ€‹

These are the questions the numbers raise. They are hers, and this document deliberately proposes no answers.

  • Should seven routes stay seven routes, given that four of them hold one card each?
  • Should a content block size to its content, as Account and Settings do, or fill the width, as the other five do? Today the portal does both.
  • What goes on Overview, which is HERS 4 and still unanswered, and does the answer change what the other pages are for?
  • Is Photos a page before image upload exists?
  • Where does a rejected offer live, and can a merchant do anything about it? See the named gap above.
  • design-survey.md, items HERS 3, HERS 4 and M6, which this supersedes for the merchant portal by measuring what M6 only counted.
  • merchant-defect-survey-0828.md, the defects, which are a different question from the design.
  • backlog.md, where the merchant dashboard parity build still waits on her ruling.

Built with VitePress