From a7bc62a5b40f0fa04882571c84298b2db0c18ee8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 23:46:11 +0000 Subject: [PATCH 1/3] feat: touch-first calculator with readable, accessible design tokens Make the app easier to use one-handed on a dock or mid-service, and fix places where text was unreadable. Readability - Add theme-aware text tokens (accent, link, success, danger) and a stronger form-control border; fix text-muted. Light text-muted was 2.6:1 and terracotta links 3.6-4.0:1; dark-mode headings that used text-brand-teal were ~2:1 (About, Data Sources, Community, Upload). - Codemod text-brand-teal/-terracotta/red-500 to the new tokens. - SyncStatusBadge used teal/gray icons on the teal navbar; use light ones. - About CTA: white on terracotta was 4.0:1; add AA-safe brand-cta. - designTokens.test.js enforces WCAG AA on every token pair. Calculator - Two numbered steps, plain-language labels, 48px controls, 16px inputs (no iOS focus zoom), Enter key calculates, result scrolls into view and is announced, disabled button explains why. - Help tooltips now work on tap and keyboard, stay on screen, and close on outside tap or Escape (were hover-only, unreadable on phones). - Labels bound to fields; "Applied to weight" shows only when a processing cost is entered; Sign in uses a router Link so a calculation is not lost to a full reload. Navigation and shell - 44px nav/menu/theme targets, skip link, aria-expanded, active-page underline, global focus ring, reduced-motion support. - Login: associate the password label, add autocomplete, center icons. - Favicon and manifest theme color match the current teal brand. Add docs/DESIGN_SYSTEM.md with token rules and known follow-ups. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01ErLEY8gicR3Wg7Q1yXAVaC --- app/index.html | 4 +- app/src/App.jsx | 60 +- app/src/components/About.jsx | 20 +- app/src/components/Calculator.jsx | 730 ++++++++++++--------- app/src/components/CommunityData.jsx | 12 +- app/src/components/ContributorProfile.jsx | 8 +- app/src/components/DataManagement.jsx | 30 +- app/src/components/DataTransparency.jsx | 44 +- app/src/components/Login.jsx | 23 +- app/src/components/PreviewPublishModal.jsx | 2 +- app/src/components/RecoveryModal.jsx | 6 +- app/src/components/SignOutGuardModal.jsx | 2 +- app/src/components/SubmitRequest.jsx | 8 +- app/src/components/SyncDetailsPanel.jsx | 2 +- app/src/components/SyncStatusBadge.jsx | 16 +- app/src/components/UploadData.jsx | 18 +- app/src/index.css | 97 ++- app/src/lib/__tests__/designTokens.test.js | 78 +++ app/tailwind.config.js | 15 +- app/vite.config.js | 4 +- docs/DESIGN_SYSTEM.md | 58 ++ 21 files changed, 801 insertions(+), 436 deletions(-) create mode 100644 app/src/lib/__tests__/designTokens.test.js create mode 100644 docs/DESIGN_SYSTEM.md diff --git a/app/index.html b/app/index.html index 91f9a27..afb160d 100644 --- a/app/index.html +++ b/app/index.html @@ -2,8 +2,10 @@ - + + + Fish Cost Calculator — Local Catch Network diff --git a/app/src/App.jsx b/app/src/App.jsx index 845caab..b9d6fc9 100644 --- a/app/src/App.jsx +++ b/app/src/App.jsx @@ -25,24 +25,24 @@ const NavBar = () => { const [syncPanelOpen, setSyncPanelOpen] = React.useState(false); const navLinkClass = ({ isActive }) => - `text-sm font-medium transition-colors ${ + `inline-flex min-h-[2.75rem] items-center text-sm font-medium transition-colors ${ isActive - ? 'text-brand-yellow' - : 'text-white/75 hover:text-white' + ? 'text-brand-yellow underline decoration-2 underline-offset-8' + : 'text-white/85 hover:text-white' }`; return ( -