fix(frontend): finish the token migration — raw grey classes -> theme tokens
UI_REDESIGN chunk 4 was never finished: 39 app/component files still used raw Tailwind greys, kept readable in light mode only by the !important override sheet. In dark mode text-gray-600 is ~2.3:1 on surface, and the light override maps it to #94a3b8 (~2.6:1 on white) — unreadable in both. Mechanical mapping (886 classes): gray-100/200 -> ink, 300/400 -> ink-2, 500/600/700 -> ink-muted, bg 950/900/800 -> page/surface/raised, border 800 -> line, 700/600 -> line-strong, plus hover/divide/placeholder. Alpha suffixes kept (tokens are color-mix, so /60 works). bg-gray-700, text-white and marketing pages left alone. text-[9px] -> text-[10px]. Frontend unverified: no Node on the authoring box (#207). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3968b49b80
commit
bf206334e3
@@ -29,25 +29,25 @@ function TripCard({ trip, isAdmin, onDelete }: {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="bg-gray-900 border border-gray-800 rounded-xl p-5 cursor-pointer hover:border-gray-700 transition-colors"
|
||||
className="bg-surface border border-line rounded-xl p-5 cursor-pointer hover:border-line-strong transition-colors"
|
||||
onClick={() => router.push(`/trips/${trip.trip_id}`)}
|
||||
>
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<span className={`text-xs font-mono px-2 py-0.5 rounded-full ${
|
||||
upcoming ? "bg-indigo-900 text-indigo-300" : "bg-gray-800 text-gray-500"
|
||||
upcoming ? "bg-indigo-900 text-indigo-300" : "bg-raised text-ink-muted"
|
||||
}`}>
|
||||
{upcoming ? "Upcoming" : "Past"}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-white font-semibold text-sm leading-snug">{trip.name}</h3>
|
||||
<p className="text-gray-400 text-xs mt-1">{trip.location}</p>
|
||||
<p className="text-gray-500 text-xs font-mono mt-1">
|
||||
<p className="text-ink-2 text-xs mt-1">{trip.location}</p>
|
||||
<p className="text-ink-muted text-xs font-mono mt-1">
|
||||
{fmtDate(trip.start_date)} — {fmtDate(trip.end_date)}
|
||||
</p>
|
||||
{attendeeCount > 0 && (
|
||||
<p className="text-gray-500 text-xs mt-1">
|
||||
<p className="text-ink-muted text-xs mt-1">
|
||||
{attendeeCount} going
|
||||
</p>
|
||||
)}
|
||||
@@ -102,59 +102,59 @@ function CreateModal({ onClose, onCreate }: {
|
||||
<div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50 p-4">
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="bg-gray-900 border border-gray-700 rounded-xl p-6 w-full max-w-md space-y-4 max-h-[90vh] overflow-y-auto"
|
||||
className="bg-surface border border-line-strong rounded-xl p-6 w-full max-w-md space-y-4 max-h-[90vh] overflow-y-auto"
|
||||
>
|
||||
<h2 className="text-white font-bold">New Trip</h2>
|
||||
|
||||
<div>
|
||||
<label className="text-xs text-gray-400 block mb-1">Name</label>
|
||||
<label className="text-xs text-ink-2 block mb-1">Name</label>
|
||||
<input
|
||||
required value={name} onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Road trip to Nashville"
|
||||
className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
className="w-full bg-raised border border-line-strong rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-xs text-gray-400 block mb-1">Location</label>
|
||||
<label className="text-xs text-ink-2 block mb-1">Location</label>
|
||||
<input
|
||||
required value={location} onChange={(e) => setLocation(e.target.value)}
|
||||
placeholder="Nashville, TN"
|
||||
className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
className="w-full bg-raised border border-line-strong rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label className="text-xs text-gray-400 block mb-1">Start date</label>
|
||||
<label className="text-xs text-ink-2 block mb-1">Start date</label>
|
||||
<input
|
||||
required type="date" value={start} onChange={(e) => setStart(e.target.value)}
|
||||
className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
className="w-full bg-raised border border-line-strong rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs text-gray-400 block mb-1">End date</label>
|
||||
<label className="text-xs text-ink-2 block mb-1">End date</label>
|
||||
<input
|
||||
required type="date" value={end} onChange={(e) => setEnd(e.target.value)}
|
||||
min={start}
|
||||
className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
className="w-full bg-raised border border-line-strong rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="text-xs text-gray-400 block mb-1">Google Maps link (optional)</label>
|
||||
<label className="text-xs text-ink-2 block mb-1">Google Maps link (optional)</label>
|
||||
<input
|
||||
type="url" value={mapsLink} onChange={(e) => setMapsLink(e.target.value)}
|
||||
placeholder="https://maps.google.com/…"
|
||||
className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
className="w-full bg-raised border border-line-strong rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{error && <p className="text-red-400 text-xs">{error}</p>}
|
||||
|
||||
<div className="flex gap-3 justify-end">
|
||||
<button type="button" onClick={onClose} className="text-sm text-gray-400 hover:text-gray-200 px-4 py-2">
|
||||
<button type="button" onClick={onClose} className="text-sm text-ink-2 hover:text-ink px-4 py-2">
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
@@ -198,12 +198,12 @@ export default function TripsPage() {
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<p className="text-gray-500 text-sm font-mono">Loading…</p>
|
||||
<p className="text-ink-muted text-sm font-mono">Loading…</p>
|
||||
) : (
|
||||
<>
|
||||
{upcoming.length > 0 && (
|
||||
<section>
|
||||
<h2 className="text-sm font-mono text-gray-400 uppercase tracking-wider mb-3">Upcoming</h2>
|
||||
<h2 className="text-sm font-mono text-ink-2 uppercase tracking-wider mb-3">Upcoming</h2>
|
||||
<div className="space-y-3">
|
||||
{upcoming.map((t) => (
|
||||
<TripCard key={t.trip_id} trip={t} isAdmin={isAdmin} onDelete={handleDelete} />
|
||||
@@ -214,7 +214,7 @@ export default function TripsPage() {
|
||||
|
||||
{past.length > 0 && (
|
||||
<section>
|
||||
<h2 className="text-sm font-mono text-gray-400 uppercase tracking-wider mb-3">Past</h2>
|
||||
<h2 className="text-sm font-mono text-ink-2 uppercase tracking-wider mb-3">Past</h2>
|
||||
<div className="space-y-3">
|
||||
{past.map((t) => (
|
||||
<TripCard key={t.trip_id} trip={t} isAdmin={isAdmin} onDelete={handleDelete} />
|
||||
@@ -224,7 +224,7 @@ export default function TripsPage() {
|
||||
)}
|
||||
|
||||
{trips.length === 0 && (
|
||||
<p className="text-gray-600 text-sm font-mono">No trips yet.</p>
|
||||
<p className="text-ink-muted text-sm font-mono">No trips yet.</p>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user