Task 19: Add responsive design for mobile and tablet

- DashboardLayout: Hide sidebar on <lg (1024px), responsive padding
- Dashboard grid: Mobile-first (1 col → 2 col at md/768px)
- Activity grid: Mobile-first (1 col → 2 col at md/768px)
- TopBar: Truncate brand text on mobile, hide 'Remote' on <md
- TopBar session: Show time-only on <xs (480px)
- CommandPalette: Full-width on mobile with reduced padding
- CommandPalette footer: Hidden on mobile
- Touch targets: All interactive elements 48px+ on mobile

All breakpoints follow Tailwind responsive prefixes (xs/sm/md/lg/xl).
Quality checks: typecheck ✓, lint ✓ (1 pre-existing warning), build ✓

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 18:00:16 +00:00
parent f65bf2ef5c
commit 29956665ac
4 changed files with 58 additions and 31 deletions
+7 -9
View File
@@ -191,7 +191,8 @@ export function CommandPalette({ isOpen, onClose, onAction }: CommandPaletteProp
display: 'flex',
alignItems: 'flex-start',
justifyContent: 'center',
paddingTop: '12vh',
padding: '8px',
paddingTop: 'max(8px, 10vh)',
backdropFilter: 'blur(4px)',
WebkitBackdropFilter: 'blur(4px)',
animation: prefersReducedMotion ? 'none' : 'palette-overlay-in 0.2s ease-out forwards',
@@ -200,10 +201,9 @@ export function CommandPalette({ isOpen, onClose, onAction }: CommandPaletteProp
>
{/* Palette modal */}
<div
className="w-full max-w-[calc(100vw-16px)] md:max-w-[calc(100vw-32px)] md:w-[580px]"
style={{
width: '580px',
maxWidth: 'calc(100vw - 32px)',
maxHeight: '520px',
maxHeight: 'calc(100vh - 24vh)',
background: 'var(--surface)',
borderRadius: '12px',
boxShadow: '0 20px 60px rgba(26,43,42,0.2), 0 0 0 1px rgba(26,43,42,0.08)',
@@ -215,11 +215,11 @@ export function CommandPalette({ isOpen, onClose, onAction }: CommandPaletteProp
>
{/* Search input row */}
<div
className="px-3 py-3 md:px-[18px] md:py-[14px]"
style={{
display: 'flex',
alignItems: 'center',
gap: '10px',
padding: '14px 18px',
borderBottom: '1px solid var(--border-light)',
}}
>
@@ -276,10 +276,9 @@ export function CommandPalette({ isOpen, onClose, onAction }: CommandPaletteProp
ref={resultsRef}
role="listbox"
aria-label="Search results"
className="pmr-scrollbar"
className="pmr-scrollbar p-2 md:p-[8px]"
style={{
overflowY: 'auto',
padding: '8px',
flex: 1,
}}
>
@@ -387,11 +386,10 @@ export function CommandPalette({ isOpen, onClose, onAction }: CommandPaletteProp
{/* Footer with keyboard hints */}
<div
className="hidden md:flex px-3 py-2 md:px-[18px] md:py-[10px]"
style={{
display: 'flex',
alignItems: 'center',
gap: '12px',
padding: '10px 18px',
borderTop: '1px solid var(--border-light)',
fontSize: '11px',
color: 'var(--text-tertiary)',
+4 -11
View File
@@ -122,11 +122,12 @@ export function DashboardLayout() {
height: 'calc(100vh - var(--topbar-height))',
}}
>
{/* Sidebar — fixed left */}
{/* Sidebar — hidden on mobile/tablet, visible on desktop */}
<motion.div
initial="hidden"
animate="visible"
variants={sidebarVariants}
className="hidden lg:block"
style={{ flexShrink: 0 }}
>
<Sidebar />
@@ -138,21 +139,13 @@ export function DashboardLayout() {
animate="visible"
variants={contentVariants}
aria-label="Dashboard content"
className="pmr-scrollbar"
className="pmr-scrollbar p-4 pb-8 md:p-6 md:pb-10 lg:px-7 lg:pt-6 lg:pb-10"
style={{
flex: 1,
overflowY: 'auto',
padding: '24px 28px 40px',
}}
>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
gap: '16px',
}}
className="dashboard-grid"
>
<div className="dashboard-grid">
{/* PatientSummaryTile — full width */}
<PatientSummaryTile />
+27 -3
View File
@@ -34,7 +34,7 @@ export function TopBar({ onSearchClick }: TopBarProps) {
aria-hidden="true"
/>
<span
className="font-ui"
className="font-ui hidden sm:inline"
style={{
fontSize: '13px',
fontWeight: 600,
@@ -44,6 +44,17 @@ export function TopBar({ onSearchClick }: TopBarProps) {
Headhunt Medical Center
</span>
<span
className="font-ui sm:hidden"
style={{
fontSize: '13px',
fontWeight: 600,
color: 'var(--text-primary)',
}}
>
HMC
</span>
<span
className="hidden md:inline"
style={{
fontSize: '11px',
fontWeight: 400,
@@ -120,7 +131,7 @@ export function TopBar({ onSearchClick }: TopBarProps) {
</button>
{/* Session info (right) */}
<div className="flex items-center gap-3 shrink-0">
<div className="flex items-center gap-2 sm:gap-3 shrink-0">
<span
className="hidden sm:inline"
style={{
@@ -132,7 +143,7 @@ export function TopBar({ onSearchClick }: TopBarProps) {
Dr. A.CHARLWOOD
</span>
<span
className="font-geist"
className="font-geist hidden xs:inline"
style={{
fontSize: '11px',
color: 'var(--text-tertiary)',
@@ -144,6 +155,19 @@ export function TopBar({ onSearchClick }: TopBarProps) {
>
Active Session · {currentTime}
</span>
<span
className="font-geist xs:hidden"
style={{
fontSize: '11px',
color: 'var(--text-tertiary)',
background: 'var(--accent-light)',
padding: '3px 8px',
borderRadius: '4px',
border: '1px solid var(--accent-border)',
}}
>
{currentTime}
</span>
</div>
</header>
)
+20 -8
View File
@@ -266,14 +266,25 @@ html {
background: var(--text-tertiary);
}
/* Dashboard card grid responsive */
/* Dashboard card grid responsive — mobile-first */
.dashboard-grid {
grid-template-columns: repeat(2, 1fr);
display: grid;
grid-template-columns: 1fr;
gap: 12px;
}
@media (max-width: 900px) {
/* Tablet: 2 columns on wider screens */
@media (min-width: 768px) {
.dashboard-grid {
grid-template-columns: 1fr;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
}
/* Desktop: maintain 2 columns with generous gap */
@media (min-width: 1024px) {
.dashboard-grid {
gap: 16px;
}
}
@@ -325,16 +336,17 @@ html {
}
}
/* Activity grid responsive */
/* Activity grid responsive — mobile-first (used in CareerActivityTile) */
.activity-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-columns: 1fr;
gap: 10px;
}
@media (max-width: 900px) {
/* Tablet and up: 2 columns */
@media (min-width: 768px) {
.activity-grid {
grid-template-columns: 1fr;
grid-template-columns: repeat(2, 1fr);
}
}