# Claims Desk — what the marketing page can say

Every value below is read out of `templates/claims-desk/` today. Where a number
is not citable, it says so instead of offering one.

> **Read this first: your six screenshots are from an older build.** Since they
> were taken the template gained a fifth destination (Sign-off), three record
> screens (claimant, notifications, and the sign-off queue), two create screens,
> and a four-view settings area. The desk now holds **19 claims, not 16**, and
> the nav reads **Work queue 2 · Sign-off 2 · Payments 2 · Responses 1 ·
> Recovery 1**. Three of the figures you listed in §7 are stale. Re-shoot before
> the page ships, or the copy will contradict its own images.

---

## 1. Routes

None of the four you have are right. `/queue` does not exist — the work queue is
the index.

| Screen | Route |
|---|---|
| Work queue | `/` |
| Claim → Assessment | `/claims/:id` |
| Claim → Evidence | `/claims/:id/evidence` |
| Claim → Decision | `/claims/:id/decision` |
| Sign-off | `/signoff` |
| Payments | `/payments` |
| Responses | `/responses` |
| Recovery | `/recovery` |
| Recovery file | `/recovery/:id` |
| Claimant | `/claimants/:id` |
| Notifications | `/notifications` |
| New claim | `/claims/new` |
| New recovery | `/recovery/new` |
| Settings (Profile · Authority · Alerts · Desk) | `/settings`, `/settings/authority`, `/settings/alerts`, `/settings/desk` |
| Sign in / Sign out | `/signin`, `/signout` |

**19 registered routes**, of which **5 are top-level destinations**. The claim's
three views and the four settings views are tabs *inside* a surface, not a second
row of navigation — worth a sentence if the page talks about IA.

### What "Responses" is

The customer's answer to the offer we made them. When a payment is sent, the
claim's file opens a response record awaiting their reply; they either accept it
or dispute it and name a figure they hold us to. The screen leads with the
disputed offer at full width — one record, not a list — beside a ledger of every
offer made.

The nav count is **disputed offers only**: today **1**, `CLM-25-0913` (Ferrymead
Automotive), who was paid **$143,900.00** and holds us to **$210,400.00** — a gap
of **$66,500.00**. Six offers have been made, five answered.

---

## 2. The status set

Your nine snake_case values are wrong in five places, and the section is
recoverable — the underlying claim is true.

**Claim status — eight values, in the order a file moves through them:**

| Value | Label on screen | Tone |
|---|---|---|
| `awaiting_documents` | Awaiting documents | neutral |
| `awaiting_survey` | Awaiting survey | neutral |
| `ready_for_decision` | Ready for decision | warning |
| `awaiting_signoff` | Awaiting sign-off | info |
| `escalated_legal` | With legal | info |
| `approved_awaiting_payment` | Approved — awaiting payment | info |
| `paid` | Paid | success |
| `rejected` | Rejected | neutral |

Corrections against what the page prints now: `escalated_to_legal` is
`escalated_legal` and reads **"With legal"**; `approved_unpaid` is
`approved_awaiting_payment`, **"Approved — awaiting payment"**;
`payment_scheduled` is not a claim status at all (it belongs to the settlement,
below); `time_barred` is not a status (below); and `awaiting_signoff` is missing
from your list entirely.

The tone grouping is worth citing, because it is the answer to a question rather
than a palette: **neutral** = waiting on somebody outside the carrier, or closed;
**warning** = waiting on the adjuster, and the only actionable tone; **info** =
waiting on another team inside the carrier; **success** = the money has left us.
`Rejected` is deliberately neutral, not danger — turning a claim down is a
decision we made and can defend, not a failure event.

**Terminal values: `paid` and `rejected`.** Everything else is open. The
predicate is one line and every screen calls it.

### Time-barred

**Your headline is true — keep it.** `time_barred` is not in the enum and is
never written. It is derived at render from `deliveredAt + 365 days`, with the
clock injected rather than read from the module, and it is listed in `enums.js`
under "deliberately absent because they are derived", alongside `overdue`,
`blocked` and `needs_signoff`. The rule the file states is: enums hold stored
state only; a record carries one status and any number of derived flags.

One caveat for §6: **no open claim in the fixture is currently past its bar.** The
nearest is `CLM-25-0977` at 47 days.

### Settlement status — a second declared set, five values

`unscheduled` "To schedule" · `scheduled` "Scheduled" · `sent` "Sent" ·
`cleared` "Cleared" · `returned` "Returned".

**Show both, and show the join.** They are not parallel: a settlement only exists
once a claim is approved, and the claim's own status stops moving once the money
is sent. `approved_awaiting_payment` covers "To schedule" and "Scheduled"; the
claim flips to `paid` when the settlement is **Sent**, and the remaining
settlement states (Cleared, Returned) happen underneath a claim that already
reads Paid. That last part is the interesting bit — a returned payment does not
reopen the claim, it reopens the payment.

There are two more declared sets if the page wants the full count:
**response status** (Awaiting response · Accepted · Disputed), **recovery
status** (To file · Filed · Negotiating · Recovered · Denied · Written off), and
**document status** (Requested · Received · Illegible). Five status fields,
**25 values** in total.

### Outcomes

Three, and yes they are separate from status: **Approve in full · Approve in
part · Reject**. An outcome is what the adjuster chose; the status is where the
file went as a result. The same outcome lands in different statuses depending on
the amount — "Approve in full" goes to `awaiting_signoff` above the authority
limit and `approved_awaiting_payment` below it.

---

## 3. What gates a decision

### The four mandatory documents

**Surveyor's report · Packing list · Commercial invoice · Delivery receipt.**

There is a fifth on the checklist, **Port photographs**, which is optional — that
is why the shot reads "3 of 4 on file" against a five-row list. On `CLM-26-0179`
the outstanding one is the **surveyor's report**, and its state is `illegible`
rather than missing: it arrived as a photograph of a screen with pages 3–7
unreadable, and was re-requested. That is a better detail than "outstanding".

The gate is one named predicate, `isDecidable` — ready for decision **and** every
mandatory document on file — and the row button, the queue headline and the nav
badge all call it.

### Authority

**Decide alone up to $25,000.00.** Above it the decision surface does *not*
change: the same three outcomes, the same justification field. What changes is
the submit button, which reads **"Send for sign-off"** instead of "Approve
claim", and the footnote beside it names the figure and the limit.

The claim then moves to `awaiting_signoff` and appears on the **Sign-off**
destination, where **Roland Achebe, claims manager** signs it. The adjuster
cannot sign her own work, so her two actions there are **Chase sign-off** and
**Withdraw decision** — the second takes the file back and reopens the
assessment. Two claims are waiting today, **$127,560.00** between them.

### The liability cap

Hague-Visby art. IV(5)(a), and **yes, always the higher** of the two
calculations: `packages × 666.67 SDR` against `kg × 2 SDR`. The payable figure is
then `min(assessed, cap)`.

The rate is **fixed in the fixture and dated**: `1.34 USD/SDR, IMF, 21 August
2026`, held once in `CLAIM_POLICY` with the date in the comment beside it. Cite
it with the date attached — that is the honest form, and it is how the product
holds it.

Three claims in the set have the cap actually bind, which is the fact worth
printing rather than the formula:

| Claim | Assessed | Cap | Basis |
|---|---|---|---|
| `CLM-26-0188` Ravenna Machine Tools | $79,060.00 | **$49,312.00** | weight |
| `CLM-25-0977` Vosges Cold Chain | $305,000.00 | **$58,960.00** | weight |
| `CLM-25-0851` Halvard Steel | $88,000.00 | **$68,608.00** | weight |

`CLM-26-0179` — the claim in your screenshot — is the opposite case, and also
worth a line: 1,240 packages against 24,600 kg puts the package basis at
**826,671 SDR** versus 49,200 SDR by weight, so the cap sits at **$1,107,738.87**
and never comes near binding. The two bases can differ by twenty times on the
same container.

---

## 4. Recovery

### The two clocks are genuinely separate — the story holds

They are different fields with different origins, and the product renders them
with the same geometry so the difference is visible rather than asserted:

- The claim's time bar is **derived**: `deliveredAt + 365 days`.
- The recovery's deadline is **stored per file** as `fileByAt`, because it comes
  from whichever contract binds that counterparty.

The proof in the data: `REC-26-0038` has **160 days** left on the terminal
handling agreement while its claim, `CLM-25-0913`, is paid and closed. And
`REC-25-0996` is **10 days past** its own deadline on a claim whose time bar
never ran out. Neither clock knows about the other.

### Counterparty types — four, not three

**Terminal · Road haulier · Packer / stuffer · Lashing contractor.**

"the terminal, the trucker, the packer" drops the lashing contractor, which is
the counterparty on the one recovery currently waiting to be filed
(`REC-26-0044`, Quayside Lashing Services, $57,600.00).

---

## 5. The audit section

**There is no audit view in the template, and there should not be one.** The
audit is a design-time discipline, not a screen: every figure names the array it
comes from, and the check is that the rows sit beside the figure, the figure
drills through to them, or it names a predicate whose list is reachable.

So the section needs to change what it points at. Two options, in order of
preference:

1. **Point it at the claim's reconciliation ledger** (`/claims/:id`). It is the
   one place the rule is visible rather than described: claimed → depreciation →
   salvage → deductible → assessed, then a hard dashed rule at the liability cap,
   then payable. No screen subtracts anything itself; one function runs the chain
   for the saved assessment and for the one the adjuster is typing, which is why
   the ledger moves as you type and the cap collision is something you watch
   happen.
2. **Keep the Payments screenshot and caption it truthfully.** The release
   pipeline above the table is five filters over the same array the table
   renders: **To schedule 1 · $56,685.00 — Scheduled 1 · $10,480.00 — Sent 1 ·
   $57,600.00 — Cleared 5 · $334,358.00 — Returned 1 · $25,600.00**, nine
   settlements totalling **$484,723.00**. Every one of those is checkable against
   the rows beneath it, which is the claim the section is trying to make.

Either way, **"Assessed payable · sums the four ready rows" has to go**: no screen
sums ready rows, and the file named `06-assessed-payable.png` is the Payments
screen.

### What the audit actually found

Four real defects, all fixed. These are better copy than the abstract claim,
because each is a specific wrong number:

1. **The work queue's Payable column printed a figure beside a Rejected badge.**
   `$28,400.00` against a claim we had turned down — arithmetically true, since a
   rejected claim still has an assessment, and operationally a lie. Now
   suppressed with a word: **"Nothing payable"**. The same trap existed for "days
   left" on a closed record.
2. **A recovery stored the money it was pursuing as well as the claim.** When the
   liability cap bit `CLM-25-0851`, the settlement fell to $68,608.00 and the
   recovery kept the pre-cap figure. The two disagreed for one build. The
   recovery now reads the settlement at render and stores nothing.
3. **A zero printed where the product's own rule is to suppress it.** The
   sign-off headline read `$0.00` with nothing waiting, while the figure beside
   it correctly degraded to a word. Now **"Nothing waiting"**.
4. **Two actions per table row pushed the table into horizontal scroll**, and the
   container's vertical scrollbar silently clipped the last row — a real defect
   caught only in a screenshot. A row now carries at most one action; the record
   name is the link.

One thing the audit deliberately did *not* "fix", which is the more interesting
line if you have room: the queue's first tab reads **On my desk 3** beside a nav
badge of **2**. They count different things — everything on the adjuster's desk
against everything she can actually finish — and the lede names the claim that
accounts for the difference (`CLM-26-0179`, held by its own evidence). The rule
is one act-ability predicate at every altitude, *or* the label says which looser
thing it counts.

---

## 6. The hostile fixtures

| Case as written | Verdict |
|---|---|
| A claim time-barred before you open it, eleven days over | **Cut it.** No open claim in the set is past its bar; the nearest is 47 days. |
| A claim escalated to legal | **Real.** `CLM-25-0977`, Vosges Cold Chain. |
| An empty group | **Too vague to print.** Replace with a named one, below. |

The "eleven days over" case has a true cousin: **`REC-25-0996` is ten days past
its contractual deadline** — a recovery, not a claim, denied by Halland Packing
Co. If the page wants a blown deadline, that is the one, and it is arguably a
better story because the deadline that expired is the contract's, not the law's.

The four you proposed are all real. For each, what a naive build does and what
this one does:

**Payment returned by the beneficiary bank** — `CLM-25-0929`, Vollmer Interiors,
**$25,600.00**, IBAN rejected. *Naive:* the claim reverts to unpaid, or the
returned money vanishes from the pipeline. *Here:* the claim stays `paid` —
the decision was correct and the customer was told — while the settlement moves
to `Returned` and rejoins "to schedule". The failure belongs to the payment, not
to the claim, and the two statuses say so independently.

**A recovery offer rejected as below the surveyed loss** — `REC-26-0022`,
Meridian Terminal Services offered **$34,000.00** against **$61,400.00** sought;
counter-proposal of $52,000.00 sent. *Naive:* the offer is stored as the
recovered amount, and the recovery rate improves the moment somebody makes any
offer. *Here:* `offerCents` and `recoveredCents` are different fields, the rate
is money-weighted over **closed files only**, and the screen says so — an open
recovery has not failed yet, and counting it would flatter or damn the rate
depending only on how much is in flight. The rate today is **20.1%**.

**A payable reading "Not assessed"** — four open claims have no assessment yet
(`CLM-26-0179`, `CLM-26-0212`, `CLM-26-0166`, `CLM-26-0154`). *Naive:* the column
renders `$0.00`, or `—`, or the amount claimed. *Here:* a figure that does not
exist yet is suppressed with a word, distinct from the word used for a claim
worth nothing ("Nothing payable"). Three states, three different strings, none of
them a zero.

**A recovery at $0.00, nothing received yet** — `REC-26-0044`, $57,600.00 sought
from Quayside Lashing Services, notice not yet served. *Naive:* a recovered
column of $0.00 in every open row, and a progress bar at zero. *Here:* the row
states what is sought and who owes the next move; the shortfall is only a figure
once the file closes.

Two more real empty states, if "an empty group" was pointing at something:
**Sign-off** shows "Nothing is waiting on a signature" once both decisions are
withdrawn, and **New recovery** refuses to render a form at all when every paid
claim is already being pursued — it is an empty state, not a disabled submit.

---

## 7. Figures you may cite

All fixture timestamps are offsets from load, so every countdown and day-count is
identical whenever the template is opened. **Nothing below drifts**; the only
reason a number changes is that somebody edits the fixture — or that a reader
takes an action in the demo, which moves the figures on purpose.

| Your figure | Status |
|---|---|
| 16 claims on the desk | **Stale — now 19.** |
| 10 open | **Stale — now 12.** |
| 3 on my desk | Correct. |
| 7 waiting on others | **Stale — now 9.** |
| 6 closed | **Stale — now 7.** |
| $751,570.00 claimed and open | **Stale — now $902,870.00.** |
| $360,800.00 inside 90 days | Correct, across 3 of the 12 open claims. |
| $451,023.00 across the payment stages | **Stale — now $484,723.00 across 9 settlements.** |

Safe additions: **2 claims decidable now**, **2 decisions worth $127,560.00
waiting on a signature**, **1 disputed offer with a $66,500.00 gap**, **5
recovery files**, **1 waiting to be filed**, **20.1% recovery rate**, **16
claimants**, **3 of whom have filed more than once**.

Product totals: **14 screens** (11 outside settings and auth, plus the four-view
settings surface and two auth screens), **19 registered routes**, **5 top-level
destinations**, **5 status fields holding 25 values**, **one fixture set**.

---

## 8. Naming

The names are invented, and the fixture is careful about it: every email address
uses the reserved `.example` TLD, which is a detail worth keeping if any address
appears in a screenshot.

That said, **I cannot promise "Corven Line" is not a real shipping company**, and
nor can the fixture. Before it goes on a public page, either run the name past a
trademark check, or — cheaper — caption the screenshots once with something like
"demonstration data" and leave it. The same applies to Meridian Terminal
Services, Quayside Lashing Services and the sixteen claimant names.

**Imogen Petrakis** and the **North Atlantic desk** are safe to print as-is:
a person who does not exist and a trade lane, not a company. If the page names
the operator at all, name the role too — "Imogen Petrakis, cargo claims adjuster"
— because the product's own account menu never shows a name without its role.

---

## 9. The walkthrough

Five screens. Each one exists because the previous screen raised a question it
could not answer, which is the shape of the argument you want.

1. **Work queue** `/` — *Which of these am I allowed to finish today?*
   The burn-down puts every open claim on one 365-day axis, so the answer is
   spatial before it is numerical. Raises: the Payable column claims a figure
   nobody has approved yet.
2. **Claim → Assessment** `/claims/:id` — *Where does that figure come from?*
   The ledger: claimed, less depreciation, salvage and the deductible, then a
   hard rule at the liability cap. Nothing on any other screen subtracts
   anything. Raises: three claims are ready for decision and only two can be
   decided.
3. **Claim → Evidence** `/claims/:id/evidence` — *Why can't I decide this one?*
   Four mandatory documents; the surveyor's report arrived illegible. Raises: the
   gate is open on the other two — what are the options?
4. **Claim → Decision** `/claims/:id/decision` — *What am I choosing between, and
   what does the customer read?*
   Three outcomes on a deliberately generous surface, with a live preview of the
   letter built from the values being typed. Raises: this one is $80,500.00, and
   the limit is $25,000.00.
5. **Sign-off** `/signoff` — *Where did it go, and how long has it been there?*
   The submitter's side of somebody else's queue. Nothing on it is hers to
   approve, and the screen says so.

If you have room for a sixth, **Recovery file** `/recovery/:id` answers the
question the whole product ends on — *we paid; who pays us?* — and it is where
the two-clocks story lives. **Payments** is better spent as the audit
screenshot (§5) than as a walkthrough step; it is the least surprising screen in
the set.
