Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/icons/icon-192.svg" />
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#014457" />
<meta name="description" content="Fish yield and cost calculator for seafood producers, chefs, and wholesalers. Part of the Local Catch Network." />
<title>Fish Cost Calculator — Local Catch Network</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
Expand Down
60 changes: 34 additions & 26 deletions app/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<nav className="bg-brand-teal sticky top-0 z-50 border-b border-white/10">
<nav aria-label="Main" className="focus-on-dark bg-brand-teal sticky top-0 z-50 border-b border-white/10">
<div className="max-w-5xl mx-auto px-4 sm:px-6">
<div className="flex items-center justify-between h-14">
{/* Logo */}
<Link to="/" className="flex items-center gap-2.5 shrink-0">
<Link to="/" className="flex min-h-[2.75rem] items-center gap-2.5 shrink-0">
<div className="w-7 h-7 bg-white/15 rounded flex items-center justify-center">
<Fish className="text-white h-4 w-4" />
</div>
<div className="leading-none">
<span className="font-semibold text-white text-sm tracking-tight">Local Catch</span>
<span className="hidden sm:inline text-white/50 text-xs ml-1.5">Fish Cost Calculator</span>
<span className="hidden sm:inline text-white/75 text-xs ml-1.5">Fish Cost Calculator</span>
</div>
</Link>

Expand Down Expand Up @@ -70,10 +70,10 @@ const NavBar = () => {
<div className="flex items-center gap-2">
<button
onClick={toggleTheme}
className="p-1.5 rounded text-white/60 hover:text-white hover:bg-white/10 transition-colors"
aria-label="Toggle theme"
className="flex h-11 w-11 items-center justify-center rounded-lg text-white/85 hover:text-white hover:bg-white/10 transition-colors"
aria-label={theme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'}
>
{theme === 'dark' ? <Sun size={16} /> : <Moon size={16} />}
{theme === 'dark' ? <Sun size={20} /> : <Moon size={20} />}
</button>

{user && (
Expand All @@ -87,18 +87,18 @@ const NavBar = () => {

{user ? (
<div className="hidden md:flex items-center gap-3">
<span className="text-white/60 text-xs">{user.username}</span>
<span className="max-w-[10rem] truncate text-white/80 text-sm">{user.username}</span>
<button
onClick={signOut}
className="text-white/70 hover:text-white text-xs border border-white/25 px-2.5 py-1 rounded transition-colors"
className="min-h-[2.5rem] text-white/85 hover:text-white text-sm border border-white/40 px-3 rounded-lg transition-colors"
>
Sign out
</button>
</div>
) : (
<Link
to="/login"
className="hidden md:flex items-center gap-1.5 text-white/75 hover:text-white transition-colors text-sm"
className="hidden md:flex min-h-[2.75rem] items-center gap-1.5 text-white/85 hover:text-white transition-colors text-sm"
>
<UserCircle className="h-4 w-4" />
Sign in
Expand All @@ -107,18 +107,20 @@ const NavBar = () => {

<button
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
className="md:hidden p-1.5 text-white/75 hover:text-white transition-colors"
aria-label="Toggle mobile menu"
className="md:hidden flex h-11 w-11 items-center justify-center rounded-lg text-white/85 hover:text-white hover:bg-white/10 transition-colors"
aria-label={mobileMenuOpen ? 'Close menu' : 'Open menu'}
aria-expanded={mobileMenuOpen}
aria-controls="mobile-menu"
>
{mobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
{mobileMenuOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
</button>
</div>
</div>
</div>

{/* Mobile menu */}
{mobileMenuOpen && (
<div className="md:hidden border-t border-white/10 bg-brand-teal">
<div id="mobile-menu" className="md:hidden border-t border-white/10 bg-brand-teal">
<div className="max-w-5xl mx-auto px-4 py-3 space-y-0.5">
{[
{ to: '/', label: 'Calculator', end: true },
Expand All @@ -134,10 +136,10 @@ const NavBar = () => {
end={end}
onClick={() => setMobileMenuOpen(false)}
className={({ isActive }) =>
`block px-3 py-2 rounded text-sm font-medium transition-colors ${
`block px-3 py-3 rounded-lg text-base font-medium transition-colors ${
isActive
? 'bg-white/15 text-white'
: 'text-white/75 hover:text-white hover:bg-white/10'
: 'text-white/85 hover:text-white hover:bg-white/10'
}`
}
>
Expand All @@ -148,10 +150,10 @@ const NavBar = () => {
<div className="pt-2 mt-2 border-t border-white/10">
{user ? (
<div className="flex items-center justify-between px-3 py-2">
<span className="text-white/60 text-sm">{user.username}</span>
<span className="text-white/80 text-base">{user.username}</span>
<button
onClick={() => { signOut(); setMobileMenuOpen(false); }}
className="text-white/70 hover:text-white text-sm"
className="min-h-[2.75rem] px-3 text-white/85 hover:text-white text-base"
>
Sign out
</button>
Expand All @@ -160,9 +162,9 @@ const NavBar = () => {
<NavLink
to="/login"
onClick={() => setMobileMenuOpen(false)}
className="flex items-center gap-2 px-3 py-2 text-sm text-white/75 hover:text-white transition-colors"
className="flex items-center gap-2 px-3 py-3 text-base text-white/85 hover:text-white transition-colors"
>
<UserCircle size={16} /> Sign in
<UserCircle size={18} /> Sign in
</NavLink>
)}
</div>
Expand All @@ -175,9 +177,15 @@ const NavBar = () => {

function AppContent() {
return (
<div className="min-h-screen bg-surface text-text-primary font-sans selection:bg-brand-terracotta/20 selection:text-brand-terracotta">
<div className="min-h-screen bg-surface text-text-primary font-sans selection:bg-brand-terracotta/20 selection:text-link">
<a
href="#main"
className="sr-only focus:not-sr-only focus:fixed focus:left-3 focus:top-3 focus:z-[60] focus:rounded-lg focus:bg-surface-raised focus:px-4 focus:py-2 focus:font-semibold focus:text-text-primary focus:shadow-lg"
>
Skip to main content
</a>
<NavBar />
<main className="py-8 px-4">
<main id="main" tabIndex={-1} className="py-6 sm:py-8 px-4 focus:outline-none">
<Analytics />
<Suspense fallback={
<div className="flex items-center justify-center py-20 text-text-muted text-sm">Loading…</div>
Expand All @@ -198,9 +206,9 @@ function AppContent() {
} />
<Route path="*" element={
<div className="max-w-2xl mx-auto text-center mt-20 space-y-4">
<p className="text-6xl font-bold text-brand-teal">404</p>
<p className="text-6xl font-bold text-accent">404</p>
<p className="text-text-secondary">Page not found.</p>
<Link to="/" className="inline-block text-brand-terracotta hover:underline text-sm font-medium">
<Link to="/" className="inline-block text-link hover:underline text-sm font-medium">
Back to calculator
</Link>
</div>
Expand Down
20 changes: 10 additions & 10 deletions app/src/components/About.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const About = () => {
<Fish className="h-10 w-10 text-white" />
</div>
</div>
<h1 className="text-3xl font-bold text-brand-teal mb-3">
<h1 className="text-3xl font-bold text-accent mb-3">
About Local Catch
</h1>
<p className="text-text-secondary max-w-xl mx-auto">
Expand All @@ -22,8 +22,8 @@ const About = () => {
{/* Origin Story */}
<div className="card p-8">
<div className="flex items-center gap-3 mb-5">
<Anchor className="h-5 w-5 text-brand-terracotta" />
<h2 className="text-xl font-semibold text-brand-teal">The Origin Story</h2>
<Anchor className="h-5 w-5 text-link" />
<h2 className="text-xl font-semibold text-accent">The Origin Story</h2>
</div>

<div className="space-y-4 text-text-secondary leading-relaxed text-sm">
Expand All @@ -34,7 +34,7 @@ const About = () => {
</p>
<p>
After some time away from active development, the project was{' '}
<span className="text-brand-terracotta font-medium">reinvigorated
<span className="text-link font-medium">reinvigorated
by a conversation on the listserv of the Local Catch network</span>. The discussions about
pricing transparency and the challenges fishers face when calculating fair prices for
their catch reminded me why this tool matters.
Expand All @@ -60,7 +60,7 @@ const About = () => {
href="https://localcatch.org"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-brand-terracotta hover:underline text-sm font-medium"
className="inline-flex items-center gap-2 text-link hover:underline text-sm font-medium"
>
Visit Local Catch Network
<ExternalLink className="h-3 w-3" />
Expand All @@ -73,13 +73,13 @@ const About = () => {
{/* Open Source */}
<div className="card p-8">
<div className="flex items-center gap-3 mb-5">
<Github className="h-5 w-5 text-brand-terracotta" />
<h2 className="text-xl font-semibold text-brand-teal">Open Source & Free Forever</h2>
<Github className="h-5 w-5 text-link" />
<h2 className="text-xl font-semibold text-accent">Open Source & Free Forever</h2>
</div>

<p className="text-text-secondary leading-relaxed mb-6 text-sm">
This calculator is and will always be{' '}
<span className="text-brand-teal font-medium">free and open source</span>.
<span className="text-accent font-medium">free and open source</span>.
It's built for and by the fishing community. Whether you're a small-scale fisher calculating
prices for direct sales, or a processor working with multiple species, this tool is here to help.
</p>
Expand All @@ -103,7 +103,7 @@ const About = () => {
</div>
</div>

<h2 className="text-xl font-semibold text-brand-teal mb-3">Support Future Updates</h2>
<h2 className="text-xl font-semibold text-accent mb-3">Support Future Updates</h2>

<p className="text-text-secondary max-w-lg mx-auto mb-6 leading-relaxed text-sm">
If you find this tool useful and want to support continued development, consider buying me a coffee!
Expand All @@ -114,7 +114,7 @@ const About = () => {
href="https://buymeacoffee.com/pcswny"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 bg-brand-terracotta hover:bg-brand-terracotta-light text-white font-semibold px-6 py-3 rounded-md transition"
className="inline-flex items-center gap-2 bg-brand-cta hover:bg-brand-cta-hover text-white font-semibold px-6 py-3 rounded-md transition"
>
<Coffee className="h-4 w-4" />
Buy Me a Coffee
Expand Down
Loading
Loading