Fix calendar popover, dropdown clipping, and header spacing across all tabs

Add dark-themed FullCalendar "+more" popover with CSS X close button
(replaces broken font icon). Add pr-8 to all mobile Select dropdowns
to prevent text clipping under chevron. Normalize header gap to
gap-2 md:gap-4 across all page headers for tighter mobile layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kyle 2026-03-11 02:13:41 +08:00
parent 023fa86b65
commit 56175aaf86
6 changed files with 79 additions and 11 deletions

View File

@ -285,7 +285,7 @@ export default function LocationsPage() {
return ( return (
<div className="flex flex-col h-full animate-fade-in"> <div className="flex flex-col h-full animate-fade-in">
{/* Header */} {/* Header */}
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0"> <div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Locations</h1> <h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Locations</h1>
<div className="w-full md:flex-1 md:w-auto min-w-0 order-last md:order-none"> <div className="w-full md:flex-1 md:w-auto min-w-0 order-last md:order-none">

View File

@ -555,7 +555,7 @@ export default function PeoplePage() {
return ( return (
<div className="flex flex-col h-full animate-fade-in"> <div className="flex flex-col h-full animate-fade-in">
{/* Header */} {/* Header */}
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0"> <div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">People</h1> <h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">People</h1>
<div className="w-full md:flex-1 md:w-auto min-w-0 order-last md:order-none"> <div className="w-full md:flex-1 md:w-auto min-w-0 order-last md:order-none">
<CategoryFilterBar <CategoryFilterBar

View File

@ -71,13 +71,13 @@ export default function ProjectsPage() {
return ( return (
<div className="flex flex-col h-full animate-fade-in"> <div className="flex flex-col h-full animate-fade-in">
{/* Header */} {/* Header */}
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0"> <div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Projects</h1> <h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Projects</h1>
<Select <Select
value={statusFilter} value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value as typeof statusFilter)} onChange={(e) => setStatusFilter(e.target.value as typeof statusFilter)}
className="h-8 text-sm w-auto md:hidden" className="h-8 text-sm w-auto pr-8 md:hidden"
> >
{statusFilters.map((sf) => ( {statusFilters.map((sf) => (
<option key={sf.value} value={sf.value}>{sf.label}</option> <option key={sf.value} value={sf.value}>{sf.label}</option>

View File

@ -100,13 +100,13 @@ export default function RemindersPage() {
return ( return (
<div className="flex flex-col h-full animate-fade-in"> <div className="flex flex-col h-full animate-fade-in">
{/* Header */} {/* Header */}
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0"> <div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Reminders</h1> <h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Reminders</h1>
<Select <Select
value={filter} value={filter}
onChange={(e) => setFilter(e.target.value as typeof filter)} onChange={(e) => setFilter(e.target.value as typeof filter)}
className="h-8 text-sm w-auto md:hidden" className="h-8 text-sm w-auto pr-8 md:hidden"
> >
{statusFilters.map((sf) => ( {statusFilters.map((sf) => (
<option key={sf.value} value={sf.value}>{sf.label}</option> <option key={sf.value} value={sf.value}>{sf.label}</option>
@ -135,17 +135,17 @@ export default function RemindersPage() {
<div className="flex-1" /> <div className="flex-1" />
<div className="relative"> <div className="relative shrink-0">
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" /> <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
<Input <Input
placeholder="Search..." placeholder="Search..."
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
className="w-32 sm:w-52 h-8 pl-8 text-sm ring-inset" className="w-28 sm:w-52 h-8 pl-8 text-sm ring-inset"
/> />
</div> </div>
<Button onClick={handleCreateNew} size="sm"> <Button onClick={handleCreateNew} size="sm" className="shrink-0">
<Plus className="h-4 w-4 md:mr-2" /><span className="hidden md:inline">Add Reminder</span> <Plus className="h-4 w-4 md:mr-2" /><span className="hidden md:inline">Add Reminder</span>
</Button> </Button>
</div> </div>

View File

@ -129,14 +129,14 @@ export default function TodosPage() {
return ( return (
<div className="flex flex-col h-full animate-fade-in"> <div className="flex flex-col h-full animate-fade-in">
{/* Header */} {/* Header */}
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0"> <div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Todos</h1> <h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Todos</h1>
{/* Priority filter */} {/* Priority filter */}
<Select <Select
value={priorityFilter} value={priorityFilter}
onChange={(e) => setPriorityFilter(e.target.value as typeof priorityFilter)} onChange={(e) => setPriorityFilter(e.target.value as typeof priorityFilter)}
className="h-8 text-sm w-auto md:hidden" className="h-8 text-sm w-auto pr-8 md:hidden"
> >
{priorityFilters.map((pf) => ( {priorityFilters.map((pf) => (
<option key={pf.value} value={pf.value}>{pf.label}</option> <option key={pf.value} value={pf.value}>{pf.label}</option>

View File

@ -193,6 +193,74 @@
font-weight: 600; font-weight: 600;
} }
/* ── FullCalendar "+more" popover fixes ── */
.fc .fc-more-popover {
background-color: hsl(0 0% 5%);
border-color: hsl(0 0% 14.9%);
border-radius: 0.5rem;
min-width: 220px;
box-shadow: 0 10px 25px -5px rgb(0 0 0 / 0.5);
}
.fc .fc-more-popover .fc-popover-header {
background-color: hsl(0 0% 7%);
color: hsl(0 0% 98%);
padding: 8px 12px;
border-radius: 0.5rem 0.5rem 0 0;
}
.fc .fc-more-popover .fc-popover-body {
padding: 8px;
}
/* Fix broken close icon — replace font icon with a CSS X */
.fc .fc-more-popover .fc-popover-close {
font-size: 0;
width: 24px;
height: 24px;
position: relative;
opacity: 0.7;
cursor: pointer;
}
.fc .fc-more-popover .fc-popover-close:hover {
opacity: 1;
}
.fc .fc-more-popover .fc-popover-close::before,
.fc .fc-more-popover .fc-popover-close::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 14px;
height: 2px;
background-color: hsl(0 0% 98%);
border-radius: 1px;
}
.fc .fc-more-popover .fc-popover-close::before {
transform: translate(-50%, -50%) rotate(45deg);
}
.fc .fc-more-popover .fc-popover-close::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
@media (max-width: 767px) {
.fc .fc-more-popover {
min-width: 200px;
}
.fc .fc-more-popover .fc-popover-body {
padding: 6px;
}
.fc .fc-more-popover .fc-daygrid-event {
font-size: 0.7rem;
padding: 2px 6px;
margin-bottom: 2px;
}
}
/* ── Chromium native date picker icon fix (safety net) ── */ /* ── Chromium native date picker icon fix (safety net) ── */
input[type="date"]::-webkit-calendar-picker-indicator, input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator { input[type="datetime-local"]::-webkit-calendar-picker-indicator {