Skip to content

feat(portal): one calm decision card on the phone (light and dark) - #208

Closed
abrichr wants to merge 3 commits into
mainfrom
feat/phone-decision-card
Closed

abrichr wants to merge 3 commits into
mainfrom
feat/phone-decision-card

Conversation

@abrichr

@abrichr abrichr commented Oct 18, 2026

Copy link
Copy Markdown
Member

Do not merge yet. Richard reviews the look first.

What changes

The phone decision page becomes one calm card per decision. Top to bottom: what is at stake (only when it is real), the question in plain words, why OpenAdapt stopped, the kept screen ("Kept 14 minutes ago · not live", tap to zoom, pinch and pan), what happens next, then the answers, then Details.

  • Answers are full-width buttons in the page flow, after the evidence. The fixed bar that covered up to half the screen is gone, and so is the separate reading gate: you reach the answers by reading the card. The first answer is still on the first 390×844 screen for the identity request.
  • Labels are plain and in sentence case: "I fixed it. Check and continue", "Stop this run", "Show OpenAdapt the right way", "Hand this to someone else", "Check what happened".
  • Emphasis rule (please confirm): one answer is filled only when exactly one answer continues the run under a live recheck and the step is not irreversible. Otherwise nothing is filled. This matches Desktop Needs you and replaces the "no answer is recommended" rule. To revert, set EMPHASIS_ENABLED.
  • Results are receipts: icon, label, title, one sentence, then the rows Your answer / Answered (on this phone · time) / Step / receipt digest.
  • New states: request expired when opened (shown as a result), request expires while open (answers close), answered elsewhere / newer request (the page re-reads the task after a refusal), offline (answers off, nothing queued), unreachable runner (Try again, pairing kept; before, the old shell cleared it), and sending.
  • Dark mode uses Desktop's dark palette. Every screen moves focus to its heading and announces it. Focus stays visible, touch targets are at least 44px, forced colours work, and motion runs only under no-preference.
  • Still a no-build PWA. The CSP, the service-worker allowlist, sessionStorage-only and no-store are unchanged.

Fail-closed rules: unchanged

The page posts only signed allowed_actions that are valid for the task. The signed digest goes back with every answer. Continuing always re-checks the live app. Expired tasks can't be answered. Nothing is queued offline. Notification templates are untouched. The request payload keys are unchanged. No contract changes.

Screens

scripts/capture_portal_scenarios.py now renders every state in light and dark mode with a fixed clock and the public OpenEMR frame. --docs refreshes docs/assets/mobile-decision/ (11 screens × 2 schemes) and its provenance. Business-decision and save-approval are labelled previews of the same card components (kind: preview); this portal does not serve them.

Tests

  • src/portalShell.test.ts: 40 tests (frame and zoom, stakes order, emphasis rules, expiry, superseded, offline, receipt, locking, navigation)
  • tests/test_portal/test_shell.py: dark mode, reduced motion, focus, no fixed bar, target size, emphasis rule, offline never unpairs
  • tests/test_portal/test_phone_captures.py (new): every receipt the shell can show is captured, and the docs assets match their provenance
  • Local: pytest tests/ 1391 passed, 1 skipped · npm run test:ui 359 passed · npm run build ok · tokens:check ok · ruff check clean

@abrichr

abrichr commented Oct 18, 2026

Copy link
Copy Markdown
Member Author

Closing: superseded by #212, merged.

@abrichr abrichr closed this Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant