refactor(ui): hide page-title H1 on mobile (header already shows it)

Mobile header strip carries the current section title in its centre
slot ("Dashboard" / "Reminders" / etc.). The top-level pages were
ALSO rendering the same string in an H1 right below — duplicate
labelling, wasted vertical space, and the H1 was the first thing
that overlapped the header on tight viewports.

Switched the four duplicates to `hidden sm:block`:
  - / (Dashboard)
  - /reminders
  - /activity
  - /settings

Desktop sidebar has no per-page title chip, so the H1 stays visible
sm: and up. Sub-pages (account detail, group detail, reminder
detail, "New Reminder", "Add Account") have dynamic H1s that don't
duplicate the header — those keep their visibility unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
yiekheng 2026-05-10 13:45:01 +08:00
parent 68d3de5ee2
commit 5d91b904f2
4 changed files with 8 additions and 4 deletions

View File

@ -184,7 +184,8 @@ export default async function ActivityPage({ searchParams }: PageProps) {
return ( return (
<div className="px-4 py-6 sm:px-6 sm:py-8 max-w-5xl mx-auto space-y-6"> <div className="px-4 py-6 sm:px-6 sm:py-8 max-w-5xl mx-auto space-y-6">
<div className="flex items-center justify-between gap-4"> <div className="flex items-center justify-between gap-4">
<h1 className="text-2xl font-semibold tracking-tight">Activity</h1> {/* Hidden on mobile — the top header already shows "Activity". */}
<h1 className="hidden sm:block text-2xl font-semibold tracking-tight">Activity</h1>
{hasAny && !showingArchived && ( {hasAny && !showingArchived && (
<Dialog> <Dialog>
<DialogTrigger asChild> <DialogTrigger asChild>

View File

@ -155,7 +155,8 @@ export default async function DashboardPage() {
return ( return (
<div className="px-4 py-6 sm:px-6 sm:py-8 max-w-5xl mx-auto space-y-8"> <div className="px-4 py-6 sm:px-6 sm:py-8 max-w-5xl mx-auto space-y-8">
<h1 className="text-2xl font-semibold tracking-tight">Dashboard</h1> {/* Hidden on mobile — the top header already shows "Dashboard". */}
<h1 className="hidden sm:block text-2xl font-semibold tracking-tight">Dashboard</h1>
{/* Stat cards — click to drill into the corresponding tab */} {/* Stat cards — click to drill into the corresponding tab */}
<div className="grid grid-cols-1 gap-4 sm:grid-cols-3"> <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">

View File

@ -182,7 +182,8 @@ export default async function RemindersPage({ searchParams }: PageProps) {
return ( return (
<div className="px-4 py-6 sm:px-6 sm:py-8 max-w-5xl mx-auto space-y-6"> <div className="px-4 py-6 sm:px-6 sm:py-8 max-w-5xl mx-auto space-y-6">
<div className="flex items-center justify-between gap-4"> <div className="flex items-center justify-between gap-4">
<h1 className="text-2xl font-semibold tracking-tight">Reminders</h1> {/* Hidden on mobile — the top header already shows "Reminders". */}
<h1 className="hidden sm:block text-2xl font-semibold tracking-tight">Reminders</h1>
<Button asChild size="sm"> <Button asChild size="sm">
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
<Link href={"/reminders/new" as any}> <Link href={"/reminders/new" as any}>

View File

@ -8,7 +8,8 @@ export default async function SettingsPage() {
const op = await getSeededOperator(); const op = await getSeededOperator();
return ( return (
<div className="container mx-auto max-w-2xl space-y-6 p-4 sm:p-6"> <div className="container mx-auto max-w-2xl space-y-6 p-4 sm:p-6">
<h1 className="text-2xl font-semibold">Settings</h1> {/* Hidden on mobile — the top header already shows "Settings". */}
<h1 className="hidden sm:block text-2xl font-semibold">Settings</h1>
<Card> <Card>
<CardHeader> <CardHeader>