A dog that eats kibble and raw meat, each with its share: the phone could show it, never write it. "Edit ration" only set the single food — on a mix's card it changed nothing you could read. The phone now composes, corrects and reads the ration the way the website does.
What you see
"Edit ration", on the Ration card of the dog's page, offers a "Compose a mix" link under the single food. Each food is a card: the food, its share as a percentage of the day's energy, "Remove". Below it, "Add a food" and the total: "Total: 100 %". When it is not 100, the screen says so ("The total is 90 %; it must be 100 %") and "Save" stays off; the same food twice, or a share left empty, are refused the same way.
With a mix, an optional calorie target: blank, it is worked out from weight and activity. With a single food, "Use the suggestion (255 g)" copies the grams the dog's page calculates.
New too, under the card: "Kennel rations". Every active dog in alphabetical order, what each gets per day (for a mix, one line per food, with its grams), then "To plan, per food" — the grams per day and per week, enough to fill the stock room — and the number of dogs without calculated grams, counted apart.
What others see, and what they don't
What you compose on the phone, the website reads as is — the same lines, the same shares — and the other way round: a mix written at the desk opens in the phone's editor. A handler, a vet or a reader see the card and the sheet, but set nothing: "Edit ration" is reserved to the kennel owner, as on the website. None of this is public: no page, no ranking, no link to share.
Offline, you can still compose. The mix is written on the phone at once and goes out at the next sync; the sheet reads without a network.
What it doesn't do
- No printable poster. The website turns the sheet into an A4 landscape poster; the phone prints nothing. That is not a choice of this change: PDF printing is an open line of the register.
- No body-condition state or ±10 % hint on the sheet. They stay on each dog's card; the phone's sheet carries none, and nothing is planned to add them.
- No "apply this ration to a whole team". That gesture stays on the website.
- No calorie target on a single food. The website shows the field, where it changes nothing; the phone doesn't show it.
Choices we made against the evidence
The shares total exactly 100, not "at most 100". The grams are worked out by spreading the energy over the sum of the shares: a mix entered as 70 / 20 would be served as 78 / 22. The screen would say one thing, the bowl would get another. No database rule holds that sum: the form does, on both sides, with the same rule.
Clearing a field really goes out — and only what you changed. Until now, clearing a ration's grams on the phone never reached the server: the value came back at the next sync, as if nothing had been done. And every save sent the whole ration again, even unchanged, at the risk of overwriting what the website had set in the meantime. Now only what changed goes out, clearing included. The other way round too: a mix emptied on the website disappears from the phone, including the kennel's last one, which used to stay on screen.
A hidden target isn't erased. If you remove every food from the mix, the target field disappears: a target set on the website stays in place. Erasing is the gesture of a screen that shows it.
Saving a mix isn't atomic, just like on the website. A mix is written by replacing the dog's one — delete, then insert — because the database only lets a client change the share of an existing line. If the insert fails after the delete, the composition is empty for a moment on the server; the send stays queued and goes out again, with nothing for you to reopen.
Lines read by decreasing share. The order came from the food's internal identifier: two lines of the same mix could swap places from one phone to another. The biggest share comes first, then the name.