refactor(ui): mobile-first pass on shared chrome + shadcn Field wrapper

- Field.tsx re-added composing shadcn Label (no built-in equivalent
  in this CLI generation).
- Bumped Input/Textarea to h-12/rounded-xl/px-4 (44px+ touch targets,
  matches the app's existing rounded, roomy input style).
- Card padding restored to the old flat p-5 sm:p-6 default so most
  call sites (`<Card>children</Card>`) don't need CardContent
  wrapping; CardHeader/Content/Footer still exported for the few
  structured cards.
- Swapped literal pink-500/gray-100 focus/border colors for
  text-primary / border-border / ring-ring tokens in Footer and
  CalendarButtons so brand color flows from the CSS vars.
- min-h-screen -> min-h-[100dvh] on full-bleed screens (home,
  create, not-found) so mobile browser chrome doesn't clip content.
- Responsive type scale (text-4xl sm:text-5xl md:text-6xl, etc.)
  instead of a single jump at md:, so headings don't overflow on
  narrow phones.
- Root layout now mounts <Toaster> and uses bg-background/
  text-foreground (background token matches the previous gray-50).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 19:42:48 +02:00
parent 9976542438
commit 5f736525fb
11 changed files with 59 additions and 33 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ const Card = React.forwardRef<
<div
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
"rounded-2xl border bg-card text-card-foreground shadow-sm p-5 sm:p-6",
className
)}
{...props}
+21
View File
@@ -0,0 +1,21 @@
import type { ReactNode } from 'react';
import { Label } from '@/components/ui/label';
interface FieldProps {
label: string;
htmlFor?: string;
hint?: string;
children: ReactNode;
}
export default function Field({ label, htmlFor, hint, children }: FieldProps) {
return (
<div className="space-y-1.5">
<Label htmlFor={htmlFor} className="text-sm font-semibold text-foreground">
{label}
</Label>
{hint && <p className="text-xs text-muted-foreground">{hint}</p>}
{children}
</div>
);
}
+1 -1
View File
@@ -8,7 +8,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
<input
type={type}
className={cn(
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"flex h-12 w-full rounded-xl border border-input bg-transparent px-4 py-2 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:border-ring disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
+1 -1
View File
@@ -9,7 +9,7 @@ const Textarea = React.forwardRef<
return (
<textarea
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"flex min-h-[80px] w-full rounded-xl border border-input bg-transparent px-4 py-3 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:border-ring disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}